JSON视图
原理:
1) 当SpringMVC读取到方法上的@ResponseBody注解时,就知道该方法不再使用默认的视图解析器解析视图,而是直接把结果写到响应体中,这样就需要对结果进行转换。
2) SpringMVC会从框架中查找有没有定义MessageConvertor(消息转换器),通过消息转换器转换结果,返回对应视图
3) 在SpringMVC的注解驱动类中,会进行默认的消息转换器注册,因为我们引入了jacksonJson包,所以会注册JSON的消息转换器
4) 因为只有JSON消息转换器可以对Java对象序列化,因此这里默认用了JSON转换
如果有多个消息转换的依赖被引入,那么就会注册多个消息转换器:例如JSONXML等等,此时会用哪个转换器?
此时会根据请求头中的accept来判断返回什么类型数据
文件上传
SpringMVC的文件上传,底层也是使用的Apache的Commons-fileupload
导包
<!-- 文件上传的依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
解析器
<!-- 定义文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
controller
@RequestMapping("/fileupload")
// 通过参数:MultipartFile file来接收上传的文件,这个是SpringMVC中定义的类,会被自动注入
public ModelAndView show21(@RequestParam("file") MultipartFile file) throws Exception {
ModelAndView mv = new ModelAndView("hello");
if(file != null){
// 将上传得到的文件 转移到指定文件。
file.transferTo(new File("D:/test/" + file.getOriginalFilename()));
}
mv.addObject("msg", "上传成功!" + file.getOriginalFilename());
return mv;
}
拦截器
HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServlet会到HandlerMapping中查找对应的Handler,找到后返回的就是这个:HandlerExecutionChain,里面包含了:
1) 正确的Handler对象
扫描二维码关注公众号,回复: 3232350 查看本文章2) Handler的拦截器集合,这里的拦截器对象是:HandlerInterceptor
拦截器接口其中定义了三个方法:
preHandle:预处理回调方法,在Handler执行前执行,第三个参数为处理器(Controller 实现);
返回值:true 表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器;
postHandle :后处理回调方法,实现处理器的后处理(但在渲染视图之前)
afterCompletion: :整个请求处理完毕回调方法,即在视图渲染完毕时回调
当然,这个接口还有一个适配器类:HandlerInterceptorAdapter,对三个方法进行了空实现。我们可以有选择的重写想要实现的方法。
正常执行流程
异常执行流程
自定义拦截器
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("**********我是拦截器1的前置处理方法。");
// 这里返回true,代表放行,如果是false,流程中断,不再执行后续的Controller中的方法了
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("**********我是拦截器1的后处理方法。我看到了View:" + modelAndView.getViewName());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("**********我是拦截器1的完成后处理方法。");
}
}
配置自定义拦截器
<!-- 配置自定义的拦截器 -->
<mvc:interceptors>
<!-- 方式1:直接在这里配置<bean> 对所有的Controller都拦截 -->
<bean class="cn.itcast.pojo.MyInterceptor1"/>
<!-- 方式2:通过mvc:interceptor来配置,同时可以指定要拦截的路径: -->
<mvc:interceptor>
<!-- 指定要拦截的路径,这里可以写固定路径,也可以使用Ant风格通配符,/**代表就是任意层数任意路径了 -->
<mvc:mapping path="/**"/>
<bean class="cn.itcast.pojo.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
拦截器的前置方法顺序执行,如果返回true,继续。返回false,流程终止,执行前面所有返回true的拦截器的完成方法
拦截器的后置方法倒序执行,在Controller执行结束后,视图解析前执行。
拦截器的完成后方法倒序执行,在视图解析后执行。无论前面是否出错或返回false,已经执行过的拦截器的完成方法都会被执行,类似于finally
获取参数的方法测试代码
package com.hrh.controller;
import com.hrh.pojo.User;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
@Controller
public class Test {
//jsp视图
@RequestMapping("testJsp")
public ModelAndView testJsp(){
ModelAndView mv = new ModelAndView("userList");
ArrayList<User> userList = new ArrayList<>();
for(int i=0;i<5;i++){
User user = new User();
user.setName("哈哈"+i);
user.setAge(10+i);
userList.add(user);
}
mv.addObject("userList",userList);
return mv;
}
//Json视图
@RequestMapping("testJson")
@ResponseBody
public List<User> testJson(){
ArrayList<User> userList = new ArrayList<>();
for(int i=0;i<5;i++){
User user = new User();
user.setName("哈哈"+i);
user.setAge(10+i);
userList.add(user);
}
return userList;
}
//直接返回视图名称
@RequestMapping("testView")
public String testView(){
return "index";
}
//视图模型分离
@RequestMapping("testViewAndModel")
public String testViewAndModel(Model model){
model.addAttribute("msg","视图模型分离..嘻嘻");
return "hello";
}
//转发和重定向
@RequestMapping("testRF")
public String testRF(){
//return "redirect:testView";
return "forward:testView";
}
//不返回视图
@RequestMapping("testVoid")
@ResponseStatus(HttpStatus.OK)
public void testVoid(){
System.out.println("hiahia");
}
//获取servlet内置对象
@RequestMapping("testServlet")
public String testServlet(HttpServletRequest request,
HttpServletResponse response,
HttpSession session){
request.setAttribute("msg","我是request啊");
response.addCookie(new Cookie("response","bu neng yong zhong wen a"));
session.setAttribute("msg2","我是session啊");
return "hello";
}
//获取PathVariable
@RequestMapping("testPathVariable/{name}&{age}")
public ModelAndView testPathVariable(@PathVariable("name")String name,
@PathVariable("age")int age){
String msg=name+"..."+age;
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg",msg);
return mv;
}
//获取基本类型参数
@RequestMapping("testParam")
public ModelAndView testParam(@RequestParam("name") String name,
@RequestParam("age") int age){
String msg=name+"..."+age;
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg",msg);
return mv;
}
//获取参数封装成pojo对象
@RequestMapping("testParamPoJo")
public ModelAndView testParamPoJo(User user){
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg",user);
return mv;
}
//获取cookie
@RequestMapping("testCookie")
public ModelAndView testCookie(@CookieValue("JSESSIONID")String jsessionid){
ModelAndView mv = new ModelAndView("hello");
mv.addObject("msg",jsessionid);
return mv;
}
//接收Json
@RequestMapping("testJson2")
@ResponseStatus(HttpStatus.OK)
public void testJson2(@RequestBody User user){
System.out.println(user.getName());
System.out.println(user.getAge());
}
//接收Json数组
@RequestMapping("testJsonArr")
@ResponseStatus(HttpStatus.OK)
public void testJsonArr(@RequestBody List<User> userList){
System.out.println(userList);
}
}