SpringMVC 学习笔记

一、SpringMVC请求流程

  1. 用户发送请求,到前端控制器(servlet,DispatcherServlet)配置在web.xml中;
  2. 前端控制器去找处理器映射器(HandlerMapping) 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理拦截器一并返回给 DispatcherServlet;
  3. 根据处理器映射器返回的处理器,DispatcherServlet 会找“合适”的处理器适配器(HandlerAdapter);
  4. 处理器适配器HandlerAdapter 会去执行处理器(Handler开发的时候会被叫成Controller也叫后端控制器)执行前会有转换器、数据绑定、校验器等等完成上面这些才会去正式执行Handler
  5. 后端控制器Handler执行完成之后返回一个ViewResolver对象
  6. 处理器适配器HandlerAdapter会将这个ModelAndView返回前端控制器DispatcherServlet 前端控制器会将ModelAndView对象交给视图解析器ViewResolver
  7. 视图解析器ViewResolver解析ViewResolver对象之后返回逻辑视图
  8. 前端控制器DispatcherServlet对逻辑视图进行渲染 (数据填充) 之后返回真正的物理View并响应给浏览器

二、配置文件

1. web.xml
    <!-- 1. 配置DispatcherServlet -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 2. 配置初始化参数 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc2.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
2. springmvc.xml
 	<!-- 1. 注解的扫描 -->
    <context:component-scan base-package="com.lyzzz"/>

    <!-- 自动配置RequestMappingHandlerMapping
              和RequestMappingHandlerAdapter注解的驱动 -->
    <mvc:annotation-driven/>

    <!-- 2. 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 3. 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!-- 不拦截登录请求 -->
            <!--<mvc:exclude-mapping path="/login"/>-->
            <bean class="com.lyzzz.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <!-- 当设置多个拦截器时,先按顺序调用preHandler方法
              然后逆序调用每个拦截器的postHandler和afterCompletion方法-->
    </mvc:interceptors>
    <!-- 4. 异常处理器 -->
    <bean id="customExceptionResolver" class="com.lyzzz.exception.CustomExceptionResolver"></bean>

    <!-- 5. 前端控制器拦截的是  /  释放静态资源的handler -->
    <mvc:default-servlet-handler/>

三、@RequestMapping注解

@RequestMapping

  1. value: 可配置多个地址
   @RequestMapping(value = {"/method1","/method2","/method3"})
   public String method()
  1. method:配置请求方式
@RequestMapping(method = {RequestMethod.POST,RequestMethod.GET})
public void method()
  1. 如有多个重复地址,可在类上添加@RequestMapping
@Controller
@RequestMapping("/param")
public class ParamController 
  1. 响应数据格式consumes:指定处理请求的提交内容的类型(content-Type)
@RequestMapping(consumes = "application/json;charset=utf-8")
// 接收json
public void method()
  1. 读取数据格式produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
@RequestMapping(produces = "application/json;charset=utf-8")
// 返回json
public void method()
  1. params:指定request中必须包含某些参数值,才让该方法处理
@RequestMapping(params = {"/num"})
public void method()
  1. headers:指定request中必须包含某些指定的header值,才让该方法处理请求
@RequestMapping(headers = {"\"Referer=http://www.hello.com/\""})
public void method()

四、@ResponseBody和 @RequestBody

  1. @ResponseBody 发送 json
 // 在方法上添加@ResponseBody,恒不跳转
 @RequestMapping(value = "/method1",produces = "application/json;charset=utf-8")
 @ResponseBody
 public String method1(){
        String json = "{\"name\":\"zs\",\"age\":\"18\"}";
        return json;
    }
  1. @RequestBody 接收 json 封装参数
 @RequestMapping(value = "/method2" ,method = {RequestMethod.POST})
 @ResponseBody
 // @RequestBody 接收json 封装参数
 public Teacher method2(@RequestBody Teacher teacher){
        System.out.println(teacher);
        return teacher;
    }

要添加jackson jar包
* tomcat报错conf>catalina.properties
* 添加 ,\ jackson-databind-2.10.0.jar,jackson-annotations-2.10.0.jar,jackson-core-2.10.0.jar

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

@RestController

 @RestController
 //设置该类的所有方法返回 JSON 数据
 //等价于 @Controller + @RequestBody

五、reseful @PathVariable

 @RequestMapping("/method6/{name}/{age}")
 public String method6(@PathVariable("name") String name, @PathVariable("age") int age){
        System.out.println(name);
        System.out.println(age);

        return "param";
    }

六、封装数据

  1. 方法参数不同 @RequestParam
 @RequestMapping("/method2")
 // 参数名称不同@RequestParam(value = "names")
 public String method2(@RequestParam(value = "names",required = true) String name, @RequestParam(defaultValue = "20") Integer age){
        System.out.println(name);
        System.out.println(age);

        return "param";
    }
  1. 日期类型
 @RequestMapping(value = "/method3")
 public String method3(Date birthday){
        System.out.println(birthday);
        return "param";
    }
 // 处理日期格式
 @InitBinder
 public void bindValue(WebDataBinder binder){
        binder.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }
  // JavaBean属性
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  private Date birthday;

七、返回值

   /**
     * Controller中方法的返回值
     * */
    // 1. 返回ModelAndView
    @RequestMapping("method1")
    public ModelAndView method1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("result","返回值是modelandview");
        modelAndView.setViewName("method1");
        return modelAndView;
    }

    // 2. 返回void
    @RequestMapping("method2")
    public void method2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 在controller形参上可以定义 request和response,并指定响应结果
        // request
        request.setAttribute("request","request");
        request.getRequestDispatcher("/WEB-INF/view/method1.jsp").forward(request,response);
       
        // session
        HttpSession session = request.getSession();
        session.setAttribute("response","response1");
        // 不能直接访问WEB-INF下的文件,受保护
        response.sendRedirect("/index.jsp");

        //  响应json
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println("{\"name\":\"中国\"}");


        String method3 = (String) request.getAttribute("method3");
        System.out.println(method3);
        String name = request.getParameter("name");
        System.out.println(name);
    }

    // 3. 返回字符串
    @RequestMapping("method3")
    public String method3(HttpServletRequest request){
        /**
         * 返回逻辑视图名
         * controller方法返回字符串可以指定逻辑视图名
         * 通过视图解析为物理视图地址
         *
         * */
        // 转发操作
        request.setAttribute("method3","转发到另一个");
        return "method1"; //转发跳转到页面
        return "forward:/return/method2"; // 转发到另一个controller
        return "redirect:/return/method2?name=zsss"; // 重定向到另一个controller

    }

八、拦截器

     *     8. 拦截器 interceptor
     *          在controller之后view视图解析之前执行
     *          过滤器和拦截器的区别
     *              1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
     *              2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
     *              3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
     *              4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
     *              5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
     *
     *          |-- 拦截器配置
     *              |-- 编写拦截器类,实现HandlerInterceptor接口,重写方法
     *              |-- springmvc.xml中配置拦截器
     *                  <!-- 配置拦截器 -->
     *                  <mvc:interceptors>
     *                      <mvc:interceptor>
     *                           <!-- 匹配url路径,如果不配置或者 设置为 "/**" 将拦截所有controller -->
     *                           <mvc:mapping path="/**"/>
     *                           <!-- 不拦截登录请求 -->
     *                           <!--<mvc:exclude-mapping path="/login"/>-->
     *                           <bean class="com.lyzzz.interceptor.MyInterceptor"/>
     *                       </mvc:interceptor>
     *                  <!-- 当设置多个拦截器时,先按顺序调用preHandler方法
     *                       然后逆序调用每个拦截器的postHandler和afterCompletion方法-->
     *                 </mvc:interceptors>
     *             |-- preHandle()
     *                  在控制器方法调用前执行,返回值为是否中断
     *                  true表示继续执行
     *                  false则会中断后续的所有操作,所以我们使用response来继续响应后续请求
     *
     *             |-- postHandle()
     *                  在控制器方法调用后,解析视图前调用
     *                  可以对模型和视图进一步进行修改或渲染
     *                  可在ModelAndView中加入数据,比如当前时间
     *
     *             |-- afterCompletion()
     *                  整个请求完成,即视图渲染结束后调用,
     *                  可做资源清理工作,或日志记录

九、异常机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值