启动服务器,加载一些配置文件
- DispatcherServlet对象被创建
- 加载Spring配置文件(bean.xml)
- 创建IOC容器
发送请求,后来处理请求
- 点击超链接
- Dispatcher接收请求,找到对应方法
- 执行方法后,然会下一个页面名称
- 使用名称通过InternalResourceViewResoler视图解析器找到要返回的页面
- 把页面返回到浏览器
RequestMapping注解
- value:请求的URL,也可以写path,当注解里只有一个值的时候可以不写value
- path:请求的URL,也可以写value,当注解里只有一个值的时候可以不写path
- method:请求方式,可是由多种请求方式访问该方法,值为RequestMethod.get,RequestMethod.post…
- params:指定请求参数的条件,必须有该参数
- headers:指定必须有该请求头
请求参数绑定
- 直接再方法名里面写参数,参数名对应表单中的参数名
<a href="user/testParams?username=hhh">请求参数绑定</a>
@RequestMapping("testParams")
public String testParams(String username){
System.out.println(username);
return "success";
}
- 把数据封装到Bean对象中
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username"><br/>
密码:<input type="text" name="password"><br/>
金额:<input type="text" name="money"><br/>
用户名:<input type="text" name="user.uname"/><br/>
年龄:<input type="text" name="user.age"><br/>
<input type="submit" value="提交">
</form>
@RequestMapping("saveAccount")
public String saveAccount(Account account){
System.out.println(account);
return "success";
}
- 带有List或者Map的对象
<!-- 把数据封装到类中,类中存在list,map -->
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username"><br/>
密码:<input type="text" name="password"><br/>
金额:<input type="text" name="money"><br/>
用户名:<input type="text" name="userList[0].uname"/><br/>
年龄:<input type="text" name="userList[0].age"><br/>
用户名:<input type="text" name="userMap['one'].uname"/><br/>
年龄:<input type="text" name="userMap['one'].age"><br/>
<input type="submit" value="提交">
</form>
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
@Data
public class Account implements Serializable {
private String username;
private String password;
private Float money;
// private User user;
private List<User> userList;
private Map<String ,User> userMap;
}
- 自定义类型转换器
<form action="param/saveUser" method="post">
用户名:<input type="text" name="uname"/><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="text" name="date"><br/>
<input type="submit" value="提交">
</form>
package com.yaku.model;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class User implements Serializable {
private String uname;
private Integer age;
private Date date;
}
需要手写一个类型转换器,实现Conversion接口
package com.yaku.utils;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 字符串转换日期
*/
public class StringToDateConverter implements Converter<String,Date> {
/**
* String s 传入的字符串
* @param s
* @return
*/
public Date convert(String s) {
if(s == null)
throw new RuntimeException("请您换入数据");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(s);
} catch (Exception e) {
throw new RuntimeException("输入数据异常");
}
}
}
然后把写好的类型转换器注册进”conversion-service“中。
<bean id="conversionServiceFactory" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.yaku.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 开启SpringMVC注解 -->
<mvc:annotation-driven conversion-service="conversionServiceFactory"/>
配置过滤器
目的:解决中文乱码问题
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
如何拿到ServletAPI对象
直接再参数列表中写你想要的API
@RequestMapping("testServlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response){
System.out.println(request);
HttpSession session = request.getSession();
System.out.println(session);
ServletContext context = session.getServletContext();
System.out.println(context);
System.out.println(response);
return "success";
}
RequestParam
作用:把请求中指定名称的参数给控制器中的形参赋值
属性:value:请求中的参数名称 required:请求中是否提供该参数,默认值:true,必须提供。
<a href="anno/testRequestParam?name=aaaa">RequestParam</a>
public String testRequestParam(@RequestParam(name="name") String name)
RequestBody
作用:用于获取请求体内容。直接得到的是key=value&key=value结构的数据,类似Json串,get方式不适用。
属性:required:是否有请求体。默认值:true,必须有请求体。
<form action="anno/testRequestBody" method="post">
用户名:<input type="text" name="uname"/><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="text" name="date"><br/>
<input type="submit" value="提交">
</form>
public String testRequestBody(@RequestBody String body){
PathVariable
作用:用于绑定url中的占位符。
属性:value:用于指定占位符的名称,
required:是否必须提供占位符。
<a href="anno/testPathVariable/10">testPathVariable</a>
@RequestMapping("testPathVariable/{sid}")
public String testPathVariable(@PathVariable("sid") String id){
System.out.println(id);
return "success";
}
restful编程风格
RequestHeader
作用:获取请求头
属性:name:指定获取哪个请求头
<a href="anno/testRequestHeader">testRequestHeader</a>
@RequestMapping("testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println(header);
return "success";
}
CookieValue
作用:用于把指定Cookie名称的值传入控制器参数
属性:value:指定Cookie的名称
required:是否必须有该Cookie
<a href="anno/testCookieValue">testCookieValue</a>
@RequestMapping("testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
System.out.println(cookieValue);
return "success";
}
ModelAttribute
作用:出现在方法上,表示当前方法会在控制器方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
出现在参数上,获取指定的数据给参数赋值。
属性:value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。
<form action="anno/testModelAttribute" method="post">
用户名:<input type="text" name="uname"/><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
@RequestMapping("testModelAttribute")
public String testModelAttribute(@ModelAttribute(value = "abc") User user){
System.out.println(user);
return "success";
}
@ModelAttribute
public void user(String uname, Map<String,User> map){
System.out.println("ModelAttribute执行了");
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setDate(new Date());
map.put("abc",user);
}
// @ModelAttribute
// public User user(String uname){
// System.out.println("ModelAttribute执行了");
// User user = new User();
// user.setUname(uname);
// user.setAge(20);
// return user;
// }
SessionAttribute
当该注解卸载累上时,把值存在session域中
往session域中存值
@RequestMapping("testSessionAttribute")
public String testSessionAttribute(Model model){
model.addAttribute("msg","yaku");
return "success";
}
从session域中取值
@RequestMapping("testSessionAttribute")
public String testSessionAttribute(Model model){
model.addAttribute("msg","yaku");
return "success";
}
清除session域中的值
@RequestMapping("removeSessionAttribute")
public String removeSessionAttribute(SessionStatus sessionStatus){
sessionStatus.setComplete();
return "success";
}
当引用内部资源(js,image,css)SpringMVC会拦截,如何处理拦截
<!-- 不拦截静态资源 -->
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/css/**" location="/css/" />
springmvc文件上传
注意表单文件框的name和接收方法的形参名称一致
@RequestMapping("/fileupload2")
public String testFileUpload2(HttpServletRequest request, MultipartFile[] upload) throws IOException {
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
if(!file.exists())
file.mkdir();
String[] filename = new String[upload.length];
for (int i = 0; i < upload.length; i++) {
String uuid = UUID.randomUUID().toString().replace("-","");
filename[i] = upload[i].getOriginalFilename();
filename[i] = uuid + filename[i];
upload[i].transferTo(new File(path,filename[i]));
}
return "success";
}
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSizePerFile" value="10485670"/>
</bean>
<form action="user/fileupload2" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"><br/>
选择文件:<input type="file" name="upload"><br/>
<input type="submit" value="上传">
</form>
SpringMVC异常处理
<!-- 配置异常处理器 -->
<bean id="SysExceptionResolver" class="com.yaku.exception.SysExceptionResolver"/>
编写异常继承Exception
@Data
public class SysException extends Exception{
//存储提示信息
private String message;
public SysException(String message){
this.message = message;
}
}
编写异常处理器实现HandlerExceptionResolver接口
package com.yaku.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SysExceptionResolver implements HandlerExceptionResolver {
/**
*
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @param e
* @return
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
SysException sysException = null;
if(e instanceof SysException)
sysException = (SysException) e;
else
new SysException("服务器正在维护...");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("errorMsg",sysException.getMessage());
return modelAndView;
}
}
拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/test/*"/>
<bean class="com.yaku.interceptor.Myinterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
编写拦截器,并且实现HandlerInterceptor
package com.yaku.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Myinterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("预处理执行了");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("后处理执行了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("jsp之后执行");
}
}