服务器启动的时候会加载web.xml,在web.xml中有下面的的配置
<servlet>
<servlet-name>webapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
这个配置的意思就是 所有的url请求都由DispatcherServlet来处理
那么问题来了,DispatcherServlet是怎么来处理的,我们需要做些什么?
DispatcherServlet是框架的类具体的实现得要看源码了,在这里不做讨论。但是我们要知道,我们做了什么来配合让框架来实现DispatcherServlet的功能。我们必须做一个配置,配置的位置和名字都有要求。比如这里名字是webapp-servlet.xml,"webapp"是根据<servlet-name>webapp</servlet-name>这里来的,位置的话放在是这样:
<!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml
这是定义然后我们来看下在webapp-servlet.xml中应该写些什么,先看下全部内容servlet.xml配置文件的位置和名称的xml语句,放在web.xml中
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value> 默认
</init-param>
-->
<?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:p="http://www.springframework.org/schema/p"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 自动扫描net.jwsz.bew.web 包下的@Controller标注的类控制器类 -->
<context:component-scan base-package="com.bieyang.popo.web.**" />
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<mvc:annotation-driven />
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />
<!-- 静态资源相关配置 -->
<bean id="rsc" class="com.bieyang.popo.web.support.spring.context.ResourceServletContext" init-method="init">
<property name="resourceRoot" value="resources" />
<property name="version" value="1.0" />
</bean>
<mvc:resources mapping="#{rsc.resourceRoot}/js/**" location="/META-INF/static/js/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/ie/**" location="/META-INF/static/ie/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/alt/**" location="/META-INF/static/alt/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/toastr/**" location="/META-INF/static/toastr/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/css/**" location="/META-INF/static/css/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/img/**" location="/META-INF/static/img/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/images/**" location="/META-INF/static/images/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/favicon.ico" location="/META-INF/favicon.ico" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/robots.txt" location="/META-INF/robots.txt" cache-period="31536000" />
<mvc:resources mapping="/robots.txt" location="/META-INF/robots.txt" cache-period="31536000" />
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>
<!-- 页面引用:<script src="${resourceRoot}/js/xx.js" type="text/javascript"></script> -->
<mvc:view-controller path="/" view-name="index" />
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" /><!-- 设置为true,可以允许多个propertyConfigurer配置 -->
<property name="location" value="classpath:bieyang-config.properties" />
</bean>
<bean id="velocityConfigurer"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/velocity/" />
<property name="configLocation" value="/WEB-INF/velocity.properties" />
<property name="velocityProperties">
<props>
<prop key="input.encoding">utf-8</prop>
<prop key="output.encoding">utf-8</prop>
<prop key="velocimacro.library">velocity-macro.vm</prop>
</props>
</property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="utf-8" p:maxUploadSize="102400000" />
<!-- <bean id="multipartResolver" -->
<!-- class="net.jwsz.bew.web.support.spring.upload.ProgressMultipartResolver" -->
<!-- p:defaultEncoding="utf-8" p:maxUploadSize="102400000" /> -->
<!-- <bean id="messageSource" -->
<!-- class="org.springframework.context.support.ResourceBundleMessageSource" -->
<!-- p:basename="i18n/messages" /> -->
<!--WEB异常解析处理 -->
<bean id="handlerExceptionResolver" class="com.bieyang.popo.web.support.spring.resolver.ExtSimpleMappingExceptionResolver">
<property name="defaultErrorView">
<value>404</value>
</property>
<property name="exceptionMappings">
<props>
<prop key="java.lang.RuntimeException">/error</prop>
<prop key="java.lang.Exception">/error</prop>
</props>
</property>
</bean>
<bean id="velocityViewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="suffix">
<value>.vm</value>
</property>
<property name="exposeSpringMacroHelpers" value="true" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="attributes">
<props>
<prop key="webServerUrl">${bieyang.popo.web.server.url}</prop>
<prop key="staticServerUrl">${bieyang.popo.static.server.url}</prop>
<prop key="photoServerUrl">${bieyang.popo.photo.server.url}</prop>
</props>
</property>
<property name="toolboxConfigLocation" value="/WEB-INF/vm/toolbox.xml" />
</bean>
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="text/html" />
<!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<!-- 用于关闭 /controller/123?format=json 的支持 -->
<property name="favorParameter" value="true" />
<property name="viewResolvers">
<list>
<ref bean="velocityViewResolver" />
</list>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<!--
检查进入DispatcherServlet的URL进行筛查,
如果发现是静态资源的请求就将该请求转由Web应用服务器默认的Servlet处理,
如果不是静态资源的请求,才由DispatcherServlet继续处理。
默认的Servlet名称是default,如果不是默认Servlet名称则需要显示指定。
-->
<!-- <mvc:default-servlet-handler default-servlet-name="webapp"/> -->
<mvc:interceptors>
<!-- <mvc:interceptor> -->
<!-- <mvc:mapping path="/**" /> -->
<!-- <bean class="com.bieyang.popo.web.interceptor.SystemContextHandlerInterceptor" /> -->
<!-- </mvc:interceptor> -->
<!-- <mvc:interceptor> -->
<!-- <mvc:mapping path="/**" /> -->
<!-- <bean class="com.bieyang.popo.web.interceptor.PermissionHandlerInterceptor"> -->
<!-- <property name="publics"> -->
<!-- <list value-type="java.lang.String"> -->
<!-- <value>/login</value> -->
<!-- <value>/getCodeImg</value> -->
<!-- </list> -->
<!-- </property> -->
<!-- </bean> -->
<!-- </mvc:interceptor> -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.bieyang.popo.web.interceptor.UserAuthHandlerInterceptorAdapter">
<property name="publics">
<list value-type="java.lang.String">
<value>/popo/login</value>
<value>/popo/logout</value>
<value>/popo/about/</value>
</list>
</property>
</bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/app/**" />
<bean class="com.bieyang.popo.app.interceptor.UserAuthHandlerInterceptorAdapter">
<property name="publics">
<list value-type="java.lang.String">
<value>/user/login</value>
<value>/reg/</value>
<value>/userinfo/homepage</value>
<value>/order/orderList</value>
<value>/guestbook/list</value>
<value>/discuss/list</value>
<value>/about/</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
现在我们来一个个分析
<!-- 自动扫描net.jwsz.bew.web 包下的@Controller标注的类控制器类 -->
<context:component-scan base-package="com.bieyang.popo.web.**" />
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<mvc:annotation-driven />这个是启用注解和url的映射
扫描com.bieyang.popo.web.**这个目录下的文件,因为这个路径下的类标注了@Controller,这样在ioc容器中就生成了bean实例。
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />这是swagger框架的东西,详细内容自己去了解http://blog.csdn.net/linlzk/article/details/50728264
然后是静态资源配置了,为什么要配置这个是因为我们在web.xml中已经配置了将所有的url都拦截,这个配置的作用就是不拦截静态资源(静态资源不是servlet处理的)。
<!-- 静态资源相关配置 -->
<bean id="rsc" class="com.bieyang.popo.web.support.spring.context.ResourceServletContext" init-method="init">
<property name="resourceRoot" value="resources" />
<property name="version" value="1.0" />
</bean> 这个以后再说,现在看不懂,这个类是自己建的继承了ServletContextAware。
<mvc:resources mapping="#{rsc.resourceRoot}/js/**" location="/META-INF/static/js/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/ie/**" location="/META-INF/static/ie/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/alt/**" location="/META-INF/static/alt/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/toastr/**" location="/META-INF/static/toastr/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/css/**" location="/META-INF/static/css/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/img/**" location="/META-INF/static/img/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/images/**" location="/META-INF/static/images/" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/favicon.ico" location="/META-INF/favicon.ico" cache-period="31536000" />
<mvc:resources mapping="#{rsc.resourceRoot}/robots.txt" location="/META-INF/robots.txt" cache-period="31536000" />
<mvc:resources mapping="/robots.txt" location="/META-INF/robots.txt" cache-period="31536000" />
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>
<!-- 页面引用:<script src="${resourceRoot}/js/xx.js" type="text/javascript"></script> -->
<mvc:view-controller path="/" view-name="index" />为了让web-inf下的index页面能直接访问
剩下的明天再说
- 指定错误处理页面,可以通过“异常类型”或“错误码”来指定错误处理页面。
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
-----------------------------
<error-page>
<exception-type>java.lang.Exception<exception-type>
<location>/exception.jsp<location>
</error-page>
<error-page>
<exception-type>java.lang.NullException</exception-type>
<location>/error.jsp</location>
</error-page>
- 设置过滤器:比如设置一个编码过滤器,过滤所有资源
<filter>
<filter-name>XXXCharaSetFilter</filter-name>
<filter-class>net.test.CharSetFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XXXCharaSetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>可以搞一个类把所有请求都检查一下编码,对请求的编码进行处理
很简单很实用的一个过滤器,当前台JSP页面和JAVA代码中使用了不同的字符集进行编码的时候就会出现表单提交的数据或者上传/下载中文名称文件出现乱码的问题,那这个类就可以出场了。
从名字就可以看出来它是个过滤器了,所以就要想配置普通过滤器那样配置到web.xml中去了,配置方式如下:
和普通过滤器配置没什么区别,就是多了两个初始化参数,两个参数的作用分别是:
encoding----->用来指定一个具体的字符集
forceEncoding------->Spring的早期版本这个参数作用很单一,当request中已经被指定了一个字符集的时候是否再将用endcoding对应的字符集设置到request中去。举个例子来说明,假如说过滤器就像上面那样被配置到web.xml了,当请求被提交之后,过滤器会判断request.getCharacterEncoding()是否为null,如果是null那么就会进行request.setCharacterEncoding("UTF-8")的操作,如果不是null那么过滤器什么也不会做。
不过Spring目前得版本这个类的代码已经被重构了,代码更加“漂亮”了,这个参数的作用也发生了细微的改变。
过滤器的请求过滤
<filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <servlet-name>webapp</servlet-name> </filter-mapping>
这个配置的作用:用HiddenHttpMethodFilter 过滤器之前大家得先了解REST风格的URL,这里简单说一下。
我们常用的请求是post跟get,而REST风格的URL还有put跟delete请求,这四种请求对应的是数据库的CURD。put对应Create,post对应Update, get对应Read,delete
当然对应delete了。
通常的浏览器都只是支持post跟get,这时候就需要HiddenHttpMethodFilter 过滤器来将post请求转换为put跟delete请求。
通过查看源代码我们知道,过滤器将post请求转换为我们对应的put跟delete请求的时候需要有一个name为_method的参数才行。废话不多说了,看下代码吧。