一、常用注解
1.@RequestParam
作用于参数上,用于提交参数与实际参数名称不一致时候生效,即name为提交的时候的参数名字,但是绑定给了username;
@RequestMapping("/anno")
public String action(@RequestParam(name="name") String username){
System.out.println(username);
return "success";
}
2.@RequestBody
作用于参数,获取POST提交参数的请求体
@RequestMapping("/anno")
public String action(@RequestBody String body){
System.out.println(body);
return "success";
}
3.@PathVariable
作用于参数,restful风格获取参数,将请求路径中的{id}封装到方法参数中
@RequestMapping("/path/{sid}")
public String path(@PathVariable(name="sid") String id){
System.out.println(id);
return "success";
}
请求路径:http://localhost:8080/path/10
控制台打印10;
4.@RequestHeader
作用于参数,获取请求头参数
@RequestMapping("/anno/header")
public String header(@RequestHeader("Cookies") String cookies){
System.out.println(cookies);
return "success";
}
5.@CookieValue
作用于参数,获取Cookies,根据键获取值
获取cookie中username的值
@RequestMapping("/anno/header")
public String header(@CookieValue("username") String username){
System.out.println(username);
return "success";
}
6.@ModelAttribute
作用于参数和方法,在方法上加上该注解泽优先于请求的controller方法执行
用处:在用户提交参数不完整的情况下,可以使用该注解来添加提交参数
@RequestMapping("/anno/modelAttr")
public String modelAttr(@ModelAttribute("attr")User user){
System.out.println(user);
return "success";
}
@ModelAttribute
public void attrPre(Map<String,User> map){
User user=new User();
user.setUsername("222");
user.setPassword("123");
map.put("attr",user);
}
这样即使即使没有提交username,password也会使用@modelAttribute方法中对应的map的user值;
7.@SessionAttributes
作用于类,用于向session域里存值
@Controller
@SessionAttributes("msg")
public class HelloController {
@RequestMapping("/anno/sessionAttr")
public String sessionAttr(ModelMap modelMap, SessionStatus sessionStatus){
//添加
modelMap.addAttribute("msg","hello sessionAttrbutes");
//获取
modelMap.get("msg");
//删除
sessionStatus.setComplete();
return "success";
}
}
二、响应数据和结果视图
1.返回值分类
1.1 String类型
Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
@RequestMapping(value="/hello")
public String sayHello() {
System.out.println("Hello SpringMVC!!");
// 跳转到XX页面
return "success";
}
1.2 void类型
- 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。在注解@RequestMapping(value="/hello") 下,默认会跳转到hello的页面,相当于返回string为hello。
- 可以使用请求转发或者重定向跳转到指定的页面
@RequestMapping(value="/init")
public void initAdd(HttpServletRequest request,HttpServletResponse response) throws
Exception {
System.out.println("请求转发或者重定向");
// 请求转发
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,
response);
// 重定向
response.sendRedirect(request.getContextPath()+"/success.jsp");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 直接响应数据
response.getWriter().print("hello mvc");
return;
}
3.ModelAndView类型
- ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
- 具体的代码如下
/**
* 返回ModelAndView对象
* 可以传入视图的名称(即跳转的页面),还可以传入对象。
*/
@RequestMapping(value="/findAll")
public ModelAndView findAll() throws Exception {
ModelAndView mv = new ModelAndView();
// 跳转到list.jsp的页面
mv.setViewName("list");
// 模拟从数据库中查询所有的用户信息
List<User> users = new ArrayList<>();
User user1 = new User();
user1.setUsername("张三");
user1.setPassword("123");
User user2 = new User();
user2.setUsername("赵四");
user2.setPassword("456");
users.add(user1);
users.add(user2);
// 添加对象
mv.addObject("users", users);
return mv;
}
2.SpringMVC框架提供的转发和重定向
controller方法返回String类型
2.1 forward转发
public String testVoid() throws Exception {
return "forward:/WEB_INF/jsp/success.jsp";
}
2.2 redirect 重定向
public String testVoid() throws Exception {
return "redirect:/index.jsp";
}
3.ResponseBody响应json数据
3.1. 配置静态资源不拦截
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而
不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置
- mvc:resources标签配置不过滤
- location元素表示webapp目录下的包下的所有文件
- mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
3.2.使用@RequestBody获取请求体数据,@ResponseBody将结果解析成json
3.2.1导入需要的jar包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
3.2.2 controller类
控制太打印post请求提交的数据,并且返回把User对象解析成json字符串返回
@RequestMapping("/testbody")
public @ResponseBody User testVoid(@RequestBody User body) throws Exception {
System.out.println(body);
return body;
}
3.2.3 ajax提交
$(function () {
$("#btn").click(function () {
$.ajax({
url:"/mvc/testbody",
contentType:"application/json;charset=utf8",
data:'{"username":"unclez","password":"zhg99524"}',
dataType:"json",
type:"post",
success:function (data) {
alert(data.username);
}
});
});
});
三、文件上传
1.传统方式
1.1 controller方法
@RequestMapping("/file")
public String fileupload1(HttpServletRequest request) throws Exception {
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
// 判断路径是否存在,如果不存在,创建该路径
if(!file.exists()) {
file.mkdirs();
}
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload sf=new ServletFileUpload(factory);
List<FileItem> items = sf.parseRequest(request);
for(FileItem item:items){
if(!item.isFormField()){
String name=item.getName();
File f=new File(path,name);
item.write(f);
item.delete();
}
}
return "success";
}
1.2 表单
<form action="/mvc/file" method="post" enctype="multipart/form-data">
名称:<input type="text" name="picname"/><br/>
图片:<input type="file" name="upload"/><br/>
<input type="submit" value="上传"/>
</form>
2.SpringMVC本服务器方式
2.1 配置文件解析器对象
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
2.1 controller类
@RequestMapping("/file")
public String fileupload1(HttpServletRequest request,MultipartFile upload) throws Exception {
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
// 判断路径是否存在,如果不存在,创建该路径
if(!file.exists()) {
file.mkdirs();
}
String filename = upload.getOriginalFilename();
filename=UUID.randomUUID()+"_"+filename;
upload.transferTo(new File(path,filename));
return "success";
}
3.SpringMVC分其他服务器上传
3.1 jar包
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
3.2 控制器
@RequestMapping("/file2")
public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception {
String server_path="远程服务器地址";
String filename = upload.getOriginalFilename();
Client client=Client.create();
WebResource resource = client.resource(server_path + filename);
resource.put(upload.getBytes());
return "success";
}
四、异常处理
1. 异常处理思路
Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。比如统一跳转404.html之类的
2.自定义异常类
public class MyException extends Exception {
// 异常提示信息
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MyException(String message) {
this.message = message;
}
}
3.自定义异常处理器
public class MyExecptionResolver implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv=new ModelAndView();
if (ex instanceof MyException)
{
mv.addObject("errorMsg",ex.getMessage());
}else {
//do something..
}
mv.setViewName("404");
return mv;
}
}
4.配置异常类
<bean id="myExecptionResolver" class="com.unclezs.resolver.MyExecptionResolver"/>
五、拦截器
1.概述
- SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
- 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
- 拦截器和过滤器的功能比较类似,有区别
- 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
- 拦截器是SpringMVC框架独有的。
- 过滤器配置了/*,可以拦截任何资源。
- 拦截器只会对控制器中的方法进行拦截。
- 拦截器也是AOP思想的一种实现方式
- 想要自定义拦截器,需要实现HandlerInterceptor接口。
2. 自定义拦截器步骤
创建类,实现HandlerInterceptor接口,重写需要的方法
3. HandlerInterceptor接口中的方法
- preHandle方法是controller方法执行前拦截的方法
- 可以使用request或者response跳转到指定的页面
- return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
- return false不放行,不会执行controller中的方法。
- postHandle是controller方法执行后执行的方法,在JSP视图执行前。
- 可以使用request或者response跳转到指定的页面
- 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
- afterHandle方法是在JSP执行后执行
- request或者response不能再跳转页面了
4.配置多个拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<!-- 哪些方法不进行拦截 -->
<!--<mvc:exclude-mapping path="/user/*"/>-->
<bean class="com.unclezs.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.unclezs.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>