zoukankan      html  css  js  c++  java
  • SpringMVC 进阶

    handler返回值

    handler方法可以是三种类型的返回值,用于不同场景

    ModelAndView

    返回值为视图和数据的包装类型,用于返回逻辑视图名称和视图需要展示的数据

    等同于在Request中添加了属性,然后进行了请求转发

    例:

    @RequestMapping("/test")
    public ModelAndView test() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index.jsp");
        modelAndView.addObject("msg", "hello ssm!");
        return modelAndView;
    }
    

    void

    表示handler不返回任何数据,用于当需要直接操作response完成响应的场景

    例:

    @RequestMapping("/test2")
    public void test2(String name,HttpServletResponse response) throws IOException {
        response.getWriter().println(name.toUpperCase());
    }
    

    String

    返回一个字符串类型的值,返回的内容可以是视图名称也可以是其他请求地址

    其背后采用的是请求转发的方式

    例:

    @RequestMapping("/test3")
    public String test3(Model model) {
        model.addAttribute("msg","hello XXX");
        return "index.jsp";
    }
    @RequestMapping("/test4")
    public String test4() {
        return "/test";
    }
    

    转发和重定向:

    也可指定对目标地址的请求是通过重定向或请求转发;

    例:

    @RequestMapping("/test5")
    public String test5() {
        return "forward:/index.jsp";
    }
    @RequestMapping("/test6")
    public String test6() {
        return "redirect:/index.jsp";
    }
    

    当然了 默认就是forward所以可以省略;

    json交互

    当下,大多数公司都会有移动端App,当我们的后台服务需要为App提供接口时,就不得不使用到json数据了,当然还有前后端分离项目中前端和后台同样采用json来交换数据;

    在开始前,需要导入jackson依赖,用于实现json的序列化与反序列化;

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.9</version>
    </dependency>
    

    返回json数据

    @ResponseBody注解用于标注一个handler方法返回的是json数据,同时方法的返回值将作为返回给前台的数据;

    例:

    @RequestMapping("/getCourseList")
    @ResponseBody
    public List<Course> getCourseList() {  //获取所有课程
        return courseService.selectCourses();
    }
    @RequestMapping("/getCourse")
    @ResponseBody
    public Course getCourse(Integer id) {// 根据id获取一个课程
        return courseService.selectByID(id);
    }
    

    ResponseBody会将响应的ContentType设置为application/json, 然后调用jackson的toJsonString将返回值转为json字符串,最后返回给客户端;

    @RestController

    如果需要为每一个方法添加ResponseBody的话,就显得非常麻烦,SpringMVC提供了@RestController注解,表示这是一个所有handler返回值全都是json的Controller,相当于把Controller和ResponseBody两个注解合并在一起;

    例:

    @RestController
    public class CourseController {.....}
    

    接受json数据

    SpringMVC可以帮助我们将json参数反序列化到指定的实体类型,List或Map;

    需要强调的是:客户端必须指定ContenType为application/json

    @RequestMapping("/addCourse")
    @ResponseBody
    public Course addCourse(@RequestBody Course course) {//接收json参数映射到实体
        course.setName("接收json成功");//修改name再把数据发回去 以便查看效果
        return course;
    }
    
    @RequestMapping("/addCourses")
    @ResponseBody
    public List<Course> addCourse(@RequestBody List<Course> courses) {//接收json数组参数映射到list
        return courses;
    }
    
    @RequestMapping("/addData")
    @ResponseBody
    public Map<String,String> addData(@RequestBody Map<String,String> data) {//接收json数据映射到map
        return data;
    }
    
    @RequestMapping("/addInfo")
    @ResponseBody
    public String addInfo(@RequestBody String data) {//接收json数据不做任何转换
        return data;
    }
    

    当客户端传递的json比较复杂时可能无法直接转换到某个实体类型,这是我们可以通过Map来接收,或直接获取原始的json字符串自己处理; 就像上面的addDataaddInfo一样

    Handler拦截器

    顾名思义Handler拦截器可对Handler方法进行拦截,控制Handler方法是否执行,与Servlet的过滤器非常相似

    但是要注意:

    ​ Servlet的filter的执行时机是在SpringMVC之前,过滤的目标对象是请求;

    ​ 而Handler拦截器,拦截的目标对象是Handler方法

    Handler拦截器可以方便的实现,登录状态验证,操作权限验证等操作;

    使用案例:

    1.编写拦截器

    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //在执行handler前调用   返回值将决定是否继续执行请求
            System.out.println("preHandle");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            //handler被真正执行了,已经拿到了handler的返回结果  但是DispatcherServlet还没有发送给前台
            System.out.println("postHandle");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            //DispatcherServlet将视图发送给前台后的回调 (无论handler是否执行 一定有响应发给前台)
            System.out.println("afterCompletion");
          
            //Handler中出现的任何异常也会传给该方法,可以在这里进行处理
    	      if (ex != null){
                System.out.println("handler中出现异常了....");
            }
        }
    }
    

    2.配置拦截器

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.kkb.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--
    * path用于指定拦截器拦截的url只有handler的url与之匹配才会被拦截  /** 表示拦截所有请求
    * interceptors中可配置多个interceptor 
    -->
    

    3.执行顺序

    拦截器的执行顺序由配置顺序来决定,拦截器也和filter一样是一个链条的形式

    在请求处理完成时,会按照相反的顺序通知interceptor(即执行afterComplation),前提是这个拦截器正常放行了请求(preHandler中返回了true),否则不会收到通知;

    异常处理

    一个完整的系统必然要考虑异常情况的处理,SpringMVC提供了一种非常方便的处理方法,只需要实现HandlerExceptionResolver接口,并注册Bean至容器中即可

    1.编写异常处理器

    @Component
    public class MyExceptionHandler implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("error.jsp");
            modelAndView.addObject("exobj",ex);
            return modelAndView;
        }
    }
    

    可以看到在处理方法的返回值为ModelAndView,我们需要在其中添加错误页面的名称和错误信息;

    2.注册到容器中

    ​ 可以直接添加Component注解或是,在配置文件中注册

    <bean class="com.kkb.exceptionhandler.MyExceptionHandler"/>
    

    强调:无论是拦截器还是异常处理器都是针对handler而不是所有请求,举个例子如果请求本身就是错误的如404,是无法被异常Handler异常处理器处理的,仍需要到web.xml来进行配置

  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/yangyuanhu/p/12304786.html
Copyright © 2011-2022 走看看