1.配置web.xml
web.xml這個(gè)是tomcat默認(rèn)自動(dòng)讀取的xml,是tomat官方規(guī)定的,一般用于配置servlet,是整個(gè)web程序的一個(gè)配置入口。最早的時(shí)候,這個(gè)web.xml的作用適用于注冊(cè)servlet、filter、listener等,tomcat讀取web.xml中的信息后,才能將url與對(duì)應(yīng)的servlet綁定起來。
??創(chuàng)建好web.xml后如圖,如下圖是2.3的老版本:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
如果想換到更高級(jí)的版本,可以在Windows的環(huán)境下,直接打開tomcat下的webapps/examples/WEB-INF目錄下的web.xml修改即可。打開該文件之后復(fù)制servlet3.1的xml頭放到項(xiàng)目的web.xml中:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmls:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web- app_3_1.xsd"
version="3.1"
metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
</web-app>
我們?cè)谑褂肧pringMVC的時(shí)候,就需要在web.xml配置一個(gè)入口,這個(gè)入口接收各種請(qǐng)求,然后再由SpringMVC框架去進(jìn)行分發(fā)。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
</param-value>
</context-param>
<filter>
<filter-name>Encoding</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 創(chuàng)建spring的監(jiān)聽器,用以啟動(dòng)容器,并加載Spring配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置前端控制器-->
<!--Dispatcher作為統(tǒng)一的訪問點(diǎn),進(jìn)行全局的流程控制。-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
【說明】
(1)web.xml加載流程
- 啟動(dòng)一個(gè)WEB項(xiàng)目的時(shí)候,容器(如:Tomcat)會(huì)去讀它的配置文件web.xml,讀兩個(gè)節(jié)點(diǎn): <listener></listener> 和 <context-param></context-param>。其中<context-param>用來聲明應(yīng)用范圍(整個(gè)WEB項(xiàng)目)內(nèi)的上下文初始化參數(shù)。
- 緊接著,容器創(chuàng)建一個(gè)ServletContext(上下文),這個(gè)WEB項(xiàng)目所有部分都將共享這個(gè)上下文。
- 容器將<context-param></context-param>轉(zhuǎn)化為鍵值對(duì),并交給ServletContext。
- 容器創(chuàng)建<listener></listener>中的類實(shí)例,即創(chuàng)建監(jiān)聽。
- 在監(jiān)聽中會(huì)有contextInitialized(ServletContextEvent args)初始化方法,在這個(gè)方法中獲得ServletContext = ServletContextEvent.getServletContext();
(2)在<context-param>部署bean.xml。
??contextConfigLocation定義了要裝入Spring的配置文件(bean.xml)。在上面的代碼中,applicationContext.xml即為bean.xml(下面會(huì)進(jìn)行配置)。下面介紹配置它的存放路徑的方法。
??Spring可以通過指定classpath*:與classpath:前綴加路徑的方式從classpath加載文件。
Java中的classpath
??src不是classpath, WEB-INF/classes,lib才是classpath,WEB-INF/ 是資源目錄, 客戶端不能直接訪問。WEB-INF/classes目錄存放src目錄Java文件編譯之后的class文件,xml、properties等資源配置文件,這是一個(gè)定位資源的入口。引用classpath路徑下的文件,只需在文件名前加classpath:。
classpath:只能加載找到的第一個(gè)classpath文件。
classpath:當(dāng)項(xiàng)目中有多個(gè)classpath路徑,并同時(shí)加載多個(gè)classpath路徑下(此種情況多數(shù)不會(huì)遇到)的文件,就發(fā)揮了作用,如果不加,則表示僅僅加載第一個(gè)classpath路徑。所以使用classpath也就可以從多個(gè)jar文件中加載相同的文件。即是以classpath*開頭,它會(huì)遍歷classpath。
??比如 resource1.jar和resource2.jar中的package 'com.test.rs' 都有一個(gè) 'jarAppcontext.xml' 文件,通過使用下面的代碼則可以將兩個(gè)jar包中的文件都加載進(jìn)來:
classpath*:com/test/rs/jarAppcontext.xml
而如果寫成下面的代碼,就只能找到其中的一個(gè)xml文件(順序取決于jar包的加載順序):
classpath:com/test/rs/jarAppcontext.xml
classpath*:的加載使用了classloader的 getResources()
方法,如果是在不同的J2EE服務(wù)器上運(yùn)行,由于應(yīng)用服務(wù)器提供自己的classloader實(shí)現(xiàn),它們?cè)谔幚韏ar文件時(shí)的行為也許會(huì)有所不同。 要測(cè)試classpath*:是否有效,可以用classloader從classpath中的jar文件里加載文件來進(jìn)行測(cè)試:getClass().getClassLoader().getResources("<someFileInsideTheJar>")。
Spring的配置文件啟動(dòng)時(shí),加載的是WEB-INF下面的bean.xml,運(yùn)行時(shí)使用的是WEB-INF/classes目錄下的bean.xml。
??在<param-value> </param-value>里指定相應(yīng)的xml文件名,如果有多個(gè)xml文件,可以寫在一起并一“,”號(hào)分隔。也可以采用通配符,如applicationContext-*.xml,,比如這那個(gè)目錄下有applicationContext-ibatis-base.xml,applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都會(huì)一同被載入。
2.配置bean.xml(application.xml)
bean.xml主要是用來配置springm的事務(wù)的,通常命名為application.xml。一個(gè)項(xiàng)目中可以有好幾個(gè)application.xml,用以配置不同的事務(wù)。這里我們使用springmvc+hibernate的配置為示例。
applicationContext.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd ">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!--引入其他bean.xml的配置-->
<import resource="applicationContext-aop.xml" />
<import resource="applicationContext-mvc.xml" />
<import resource="applicationContext-mybatis.xml" />
<import resource="applicationContext-transaction.xml" />
<import resource="applicationContext-task.xml" />
<import resource="applicationContext-redis.xml" />
</beans>
【說明】
(1)PropertyPlaceholderConfigurer是spring提供我們來把一些環(huán)境變量(數(shù)據(jù)庫(kù)連接相關(guān)參數(shù),文件路徑等)統(tǒng)一管理起來,然后在bean中指定對(duì)應(yīng)的變量的。實(shí)際上,PropertyPlaceholderConfigurer起的作用就是將占位符指向的數(shù)據(jù)庫(kù)配置信息放在bean中定義。
applicationContext-aop.xml(配置AOP)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!--開啟注解式AOP-->
<aop:aspectj-autoproxy />
</beans>
applicationContext-mybatis.xml(配置數(shù)據(jù)源)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 初始化連接大小 -->
<property name="initialSize" value="${jdbc.initialSize}"></property>
<!-- 連接池最大數(shù)量 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!-- 基于sqlSessionTemplate的mybatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:mapper/*.xml" />
</bean>
<!-- sqlSessionTemplate配置 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
applicationContext-transaction.xml(配置事務(wù))
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--開啟注解式事務(wù)-->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
applicationContext-mvc.xml(配置SpringMVC)
<?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: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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!--通過annotation來配置控制器 -->
<mvc:annotation-driven/>
<!--配置靜態(tài)資源的訪問-->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />
<!-- 掃描有注解的文件 base-package 包路徑 -->
<context:component-scan base-package="com.zyt.controller" />
<context:component-scan base-package="com.zyt.dao" />
<context:component-scan base-package="com.zyt.service" />
</beans>
【說明】
(1)<mvc:annotation-driven />、<context:annotation-config />和<context:component-scan>的區(qū)別
<context:annotation-config> declares support for general annotations such as @Required, @Autowired, @PostConstruct, and so on.<context:annotation-config>主要是解決spring容器的一些注解。
<mvc:annotation-driven /> is actually rather pointless. It declares explicit support for annotation-driven MVC controllers (i.e.@RequestMapping, @Controller, etc), even though support for those is the default behaviour.<mvc:annotation-driven />是spring MVC為@Controllers分發(fā)請(qǐng)求所必須的,并提供了數(shù)據(jù)綁定支持。
<context:component-scan>做了<context:annotation-config>要做的事情,還額外支持@Component,@Repository,@Service,@Controller注解。并且<context:component-scan>掃描base-package并且在application context中注冊(cè)掃描的beans。所以配置<context:component-scan>就不需要配置<context:annotation-config/>
(2)<mvc:resources>標(biāo)簽的作用
??我們知道Dispatcher的servlet會(huì)使用 / 攔截了所有的請(qǐng)求,而對(duì)靜態(tài)資源的訪問也屬于一個(gè)請(qǐng)求,然后進(jìn)入它的匹配流程,根據(jù)HandlerMapping的配置來匹配的。但是對(duì)于靜態(tài)資源來說,默認(rèn)的Spring MVC是沒有注冊(cè)匹配規(guī)則的,此時(shí)若你去請(qǐng)求一個(gè)靜態(tài)資源,則會(huì)報(bào)404錯(cuò)誤,比如頁(yè)面上引用的css,js等效果不起作用了。怎么辦呢?這里有3種方法。
- 配置一個(gè)處理靜態(tài)資源的HandlerMapping
<bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
<property name="locations" value="classpath:/META-INF/resources/"></property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/resources/**">ResourceHttpRequestHandler</prop>
</props>
</property>
</bean>
其中ResourceHttpRequestHandler就是處理靜態(tài)資源請(qǐng)求的類,當(dāng)然如果你愿意,也可以自己嘗試寫一個(gè)。
- 采用spring自帶<mvc:resources>方法。
//location是工程路徑地址,mapping是映射后的訪問地址
<mvc:resources mapping="/images/**" location="/static_resources/images/"/>
<mvc:resources />由Spring MVC框架自己處理靜態(tài)資源,并添加一些有用的附加值功能。本質(zhì)上也是把ResourceHttpRequestHandler注冊(cè)到SimpleUrlHandlerMapping上。
??<mvc:resources />允許靜態(tài)資源放在任何地方,如WEB-INF目錄下、類路徑下等,你甚至可以將JavaScript等靜態(tài)文件打到JAR包中。通過location屬性指定靜態(tài)資源的位置,由于location屬性是Resources類型,因此可以使用諸如"classpath:"等的資源前綴指定資源位置。傳統(tǒng)Web容器的靜態(tài)資源只能放在Web容器的根路徑下,<mvc:resources />完全打破了這個(gè)限制。
- 采用<mvc:default-servlet-handler/> 方法。
<mvc:default-servlet-handler/>
<mvc:default-servlet-handler/> 只能在SpringMVC3.0之后使用,且對(duì)于匹配規(guī)則為"/"的DispatcherServlet才生效(因?yàn)閯e的匹配規(guī)則一般也不會(huì)攔截靜態(tài)資源)。配置<mvc:default-servlet-handler />后,會(huì)在Spring MVC上下文中定義一個(gè)org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler。它會(huì)像一個(gè)檢查員,對(duì)進(jìn)入DispatcherServlet的URL進(jìn)行篩查,如果發(fā)現(xiàn)是靜態(tài)資源的請(qǐng)求,就將該請(qǐng)求轉(zhuǎn)由Web應(yīng)用服務(wù)器默認(rèn)的Servlet處理,如果不是靜態(tài)資源的請(qǐng)求,才由DispatcherServlet繼續(xù)處理。