• SpringMVC 细节学习


    使用Spring MVC,配置DispatcherServlet是第一步 

    DispatcherServlet是前置控制器,配置在web.xml文件中的 。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(我们写的Action)来处理。

    “某某规则”:是根据你使用了哪个HandlerMapping接口的实现类的不同而不同。 

    <web-app>

    <servlet>
    <servlet-name>example</servlet-name>                   //这个Servlet的名字是example
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>                    //是启动顺序,让这个Servlet随Servletp容器一起启动
    </servlet>
    <servlet-mapping>
    <servlet-name>example</servlet-name>
    <url-pattern>*.form</url-pattern>                          //会拦截*.form结尾的请求
    </servlet-mapping>
    </web-app>
      在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean。

     第二个例子:

    <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>

     指明了配置文件的文件名,不使用默认配置文件名,而使用springMVC.xml配置文件。

    其中<param-value>**.xml</param-value> 这里可以使用多种写法
    1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
    2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
    3、<param-value>classpath*:springMVC-mvc.xml</param-value>
    4、多个值用逗号分隔
    Servlet拦截匹配规则可以自已定义,拦截哪种URL合适?
    当映射为@RequestMapping("/user/add")时,为例:
    1、拦截*.do、*.htm, 例如:/user/add.do
    这是最传统的方式,最简单也最实用。不会导致静态文件(jpg,js,css)被拦截。

     2、拦截/,例如:/user/add

    可以实现现在很流行的REST风格。很多互联网类型的应用很喜欢这种风格的URL。
    弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。想实现REST风格,事情就是麻烦一些。后面有解
    决办法还算简单。
    3、拦截/*,这是一个错误的方式,请求可以走到Action中,但转到jsp时再次被拦截,不能访问到jsp。
    springMVC-mvc.xml 配置文件片段讲解(未使用默认配置文件名)
     

    <?xml version="1.0" encoding="UTF-8"?>

    <beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <!-- 自动扫描的包名 -->
    <context:component-scan base-package="com.app,com.core,JUnit4" ></context:component-scan>
    <!-- 默认的注解映射的支持 -->
    <mvc:annotation-driven />
    <!-- 视图解释类 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    </bean>
    <!-- 拦截器 -->
    <mvc:interceptors>
    <bean class="com.core.mvc.MyInteceptor" />
    </mvc:interceptors>
    <!-- 对静态资源文件的访问 方案一 (二选一) -->
    <mvc:default-servlet-handler/>
    <!-- 对静态资源文件的访问 方案二 (二选一)-->
    <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>
    <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>
    <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>
    </beans>

     <context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有:

    @Controller 声明Action组件
    @Service 声明Service组件@Service("myMovieLister")
    @Repository 声明Dao组件
    @Component 泛指组件, 当不好归类时.
    @RequestMapping("/menu") 请求映射
    @Resource 用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")
    @Autowired 用于注入,(srping提供的) 默认按类型装配
    @Transactional( rollbackFor={Exception.class}) 事务管理
    @ResponseBody
    @Scope("prototype") 设定bean的作用域

     请求如何映射到具体的Action中的方法?

    并在action类上使用:
    @Controller
    @RequestMapping("/user")

     、Spring中的拦截器:

    Spring为我们提供了:
    org.springframework.web.servlet.HandlerInterceptor接口,
    org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器,
    实现这个接口或继承此类,可以非常方便的实现自己的拦截器。
    有以下三个方法:
    Action之前执行:
    public boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, Object handler);
    生成视图之前执行
    public void postHandle(HttpServletRequest request,
    HttpServletResponse response, Object handler,
    ModelAndView modelAndView);

     最后执行,可用于释放资源

    public void afterCompletion(HttpServletRequest request,
    HttpServletResponse response, Object handler, Exception ex)

    分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)
    在preHandle中,可以进行编码、安全控制等处理;
    在postHandle中,有机会修改ModelAndView;
    在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
    参数中的Object handler是下一个拦截器。

     十、如何使用拦截器?

    自定义一个拦截器,要实现HandlerInterceptor接口:
    public class MyInteceptor implements HandlerInterceptor {
    略。。。
    }

    拦截器会在什么时候执行呢? 一个请求交给一个HandlerMapping时,这个HandlerMapping先找有没有处理器来处理这个
    请求,如何找到了,就执行拦截器,执行完拦截后,交给目标处理器。
    如果没有找到处理器,那么这个拦截器就不会被执行。

     在spring MVC的配置文件中配置有三种方法

    方案一,(近似)总拦截器,拦截所有url
    <mvc:interceptors>
    <bean class="com.app.mvc.MyInteceptor" />
    </mvc:interceptors>

    <mvc:interceptors/>会为每一个HandlerMapping,注入一个拦截器。总有一个HandlerMapping是可以找到处理器的, 最多也只找到一个处理器,所以这个拦截器总会被执行的。起到了总拦截器的作用。
    方案二, (近似) 总拦截器, 拦截匹配的URL。
    <mvc:interceptors >
    <mvc:interceptor>
    <mvc:mapping path="/user/*" /> <!-- /user/* -->
    <bean class="com.mvc.MyInteceptor"></bean>
    </mvc:interceptor>
    </mvc:interceptors>

    方案三,HandlerMappint上的拦截器。
    如果是REST风格的URL,静态资源就不会被拦截。因为我们精准的注入了拦截器。
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
    <list>
    <bean class="com.mvc.MyInteceptor"></bean>
    </list>
    </property>
    </bean>
    如果使用了<mvc:annotation-driven />, 它会自动注册DefaultAnnotationHandlerMapping 与
    AnnotationMethodHandlerAdapter 这两个bean,所以就没有机会再给它注入interceptors属性,就无法指定拦截器。
    当然我们可以通过人工配置上面的两个Bean,不使用<mvc:annotation-driven />,就可以给interceptors属性注入拦截
    器了。
    其实我也不建议使用<mvc:annotation-driven />,而建议手动写详细的配置文件,来替代<mvc:annotation-driven />,
    这就控制力就强了。
  • 相关阅读:
    ASP.NET中的特殊路径标识"~"
    ASP.NET中的Request、Response、Server对象
    XSS漏洞(跨站脚本)
    WEB开发原则
    HTTP协议
    【原】从零开始改造淘淘商城(引入dubbo解决项目耦合)02
    【转】Nginx的启动、停止与重启
    【原】spring boot添加cros全局过滤器
    【转】Swagger2 添加HTTP head参数
    【原】Spring Boot 配置swagger2没有文档解决方案
  • 原文地址:https://www.cnblogs.com/daniell003/p/3443573.html
Copyright © 2020-2023  润新知