zoukankan      html  css  js  c++  java
  • SpringMVC 入门

    一、SpringMVC架构

    SpringMVC框架主要分为四个部分:DispatcherServlet、HandlerMapping、Controller、ViewResolver

    903382-20161220180549026-70303073

    1、DispatcherServlet

    DispatcherServlet(前端控制器)提供Spring MVC的几种访问点,而且负责职责的调度,用于控制流程,主要职责:

    • 文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
    • 通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);
    • 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
    • 通过ViewResolver解析逻辑视图名到具体视图实现;
    • 本地化解析;
    • 渲染具体的视图等;
    • 如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。

    DispatcherServlet具体工作流程如下:

    • 拦截符合特定格式的URL请求
    • 初始化DispatcherServlet上下文对应的WebApplicationContext,并于业务层、持久层建立联系
    • 初始化SpringMVC的各个组件,并装配到DispatherServlet中

    DispatcherServlet需要在Web.xml中进行正确配置,才能接受http请求并组织协调SpringMVC的各个组成部分。

    <servlet>
      <servlet-name>springMVC</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/springMVC.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>

    param-name:contextConfigLocation 不可更改

    param-value:DispatcherServlet的配置文件,如果不指定该参数,则默认配置文件为/WEB-INF/<servlet-name>-servlet.xml。

    load-on-startup:定义为1表示启动容器时初始化该Servlet;

    url-pattern定义要拦截的URL请求。

    拦截规则:

    • *.xxx,指定要拦截的特定类型,最简单实用的方式,并且不会拦截静态文件 ,例如*.html 标致拦截所有以html为扩展名的请求
    • /,标识所有请求都通过DIspatcherServlet来处理

    2、处理映射HandlerMapping

         通过处理器映射,你可以将Web请求映射到正确的处理器Controller上。当接收到请求时,DispatcherServlet将请求交给HandlerMapping处理器映射,让它检查请求并找到一个适当的HandlerExecutionChain,这个HandlerExecutionChain包含一个能处理该请求的处理器Controller。然后,DispatcherServlet执行定义在HandlerExecutionChain中的处理器Controller。

    SpringMVC有四种映射处理器handlerMapping:

    1)、BeanNameUrlHandlerMapping

    该处理器是默认开启的,再spring-mvc.xml中配置:

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <bean id="helloController" name="/hello" class="com.controller.HelloController"></bean>

    新建HelloController.java

    public class HelloController implements Controller {
        public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
            //do your things here...
            return new ModelAndView("hello");
        }
    }

    新建hello.jsp

    配置好后,启动程序,在浏览器中输入http://localhost:8080/hello

    image

    2)、SimpleUrlHandlerMapping

    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <value>
                    /hello=helloController
                </value>
            </property>
        </bean>
        <bean id="helloController" class="com.test.ssm.controller.HelloController"/>

    这种映射的优点是将映射器于Controller的定义分开,解耦

    3)、ControllerClassNameHandlerMapping

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>
    <bean id="hello3Controller" class="com.test.ssm.controller.HelloController"></bean>

    启动后浏览器中输入:http://localhost:8080/helloController,即可顺利进入页面

    4)、DefaultAnnotationHandlerMapping

    使用注解来映射寻找Controller,这个应该是目前最常用的方式

    <beans>
    <!--配置扫描使用注解的包路径  -->
    <context:component-scan base-package="com"></context:component-scan>
    <!--开启springMVC注解  -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>  
    </beans>

    在类上标记:@Controller 声明该类是一个springMVC Controller
    在方法上使用:@RequestMapping("/user") 声明该方法处理哪一个请求

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @Resource
        private IUserService userService;
    
        @RequestMapping("/showUser")
        @ResponseBody
        public User getUserByID(HttpServletRequest request, Model model) {
            int userId = Integer.parseInt(request.getParameter("id"));
            User user = this.userService.getUserByID(userId);
            //绑定对象到User.jsp
            //model.addAttribute("user", user);
            return user;
        }
        @RequestMapping(value="/saveUser",method=RequestMethod.POST)
        @ResponseBody
        public Result postData(@RequestBody String userJson) {
            User user = JSON.parseObject(userJson, User.class);
            userService.saveUser(user);
            Result r = new Result();
            r.setResCode(0);
            r.data.setMsg("success");
            return r;
        }

    在浏览器中输入:http://localhost:8080/user/showUser?id=1

    image

    3、控制器Controller

    负责处理用户请求,完成之后返回ModelAndView对象给DispatcherServlet

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @Resource
        private IUserService userService;
    
        @RequestMapping("/showUser")
        @ResponseBody
        public User getUserByID(HttpServletRequest request, Model model) {
            int userId = Integer.parseInt(request.getParameter("id"));
            User user = this.userService.getUserByID(userId);
            //绑定对象到User.jsp
            //model.addAttribute("user", user);
            return user;
        }
        @RequestMapping(value="/saveUser",method=RequestMethod.POST)
        @ResponseBody
        public Result postData(@RequestBody String userJson) {
            User user = JSON.parseObject(userJson, User.class);
            userService.saveUser(user);
            Result r = new Result();
            r.setResCode(0);
            r.data.setMsg("success");
            return r;
        }

    4、视图解析器ViewResolver

    暂略

    二、工作原理

    1. 将客户端请求提交给DispatcherServlet
    2. 根据<servlet-name>servlet.xml的配置,查找HandlerMapping
    3. 通过HandlerMapping找到处理请求的具体Controller
    4. Controller调用业务逻辑处理
    5. 处理完成之后,返回ModelAndView对象给DispatcherServlet
    6. 通过ViewResolver找到负责显示的具体View
    7. 由View将结果渲染到客户端

    三、常用注解

    • @Controller:声明Action组件,负责注册bean到Spring上下文
    • @RequestMapping:用于为控制器指定可以处理的url请求
    • @RequestParam:用于指定参数的name属性
    • @RequestBody:用于读取Request请求的body部分数据
    • @ResponseBody:用于将控制器方法返回的对象写入到Response对象的body数据区
    • @PathVariable:用于指定url作为参数
    • @Resource用于注入,( 由j2ee提供 ) 默认按名称装配
    • @Autowired用于注入,(由spring提供) 默认按类型装配
    • @ExceptionHandler:用于异常处理的方法
    • @ControllerAdvice:用于使控制器成为全局的异常处理类
    • @ModelAttribute:用于优先调用被注解的方法,或注解参数中的隐藏对象

    四、拦截器

    Spring提供了HandlerInterceptor接口和HandlerInterceptorAdapter适配器。实现这个接口或继承此类,就可以实现自己的拦截器。接口HandlerInterceptor包含三个方法,每个方法的参数handler,用来指向下一个拦截器。

    • preHandle(),在Action之前执行的预处理,可以进行编码、安全控制等处理
    • postHandle(),在生成View之前执行的后处理,调用了Service并返回ModelAndView,但未进行页面渲染,可以修改ModelAndView
    • afterCompletion(),最后执行的返回处理,这时已经进行了页面渲染,可以进行日志记录、释放资源等处理

    在实现了接口之后,就可以在配置文件中进行拦截器的配置。

    public class TestInteceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("我被拦截了: preHandle");
            return super.preHandle(request, response, handler);
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("我被拦截了: postHandle");
            super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("我被拦截了: afterCompletion");
            super.afterCompletion(request, response, handler, ex);
        }
    }
    image 
  • 相关阅读:
    BZOJ 3527: [Zjoi2014]力 [快速傅里叶变换]
    BZOJ 2194 [快速傅里叶变换 卷积]
    BZOJ 2179 [快速傅里叶变换 高精度乘法]
    [快速傅立叶变换&快速傅里叶变换]【旧 手写笔记】
    CF 235C. Cyclical Quest [后缀自动机]
    BZOJ 1396&&2865 识别子串[后缀自动机 线段树]
    BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]
    BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]
    BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
    BZOJ 3473: 字符串 [广义后缀自动机]
  • 原文地址:https://www.cnblogs.com/jimmy-y/p/9174609.html
Copyright © 2011-2022 走看看