現在介紹SSH的文章很多,但是適合自己需求的卻經常找不到,這些東西呢,會了之后總會感覺別人的程序哪里哪里別扭,會之前呢就感覺很混亂,而且SSH的官方文檔,至少在我看來是“會者勉強能看、不會者一片迷茫”的,最主要的是沒有什么demo,也可能因為我太low了,高手勿噴,我的感覺就是根據文檔呢很容易明白如果寫了A就能怎么樣寫了B又能怎么樣,但是這個A或者B到底寫在哪能讓程序跑起來呢,更是會者不難、難者不會。我隔了兩年沒有做這方面的項目,最近重新拾起來,不再用struts,用spring、spring mvc、hibernate、spring security、spring oauth2搭建網站,這篇包括下面幾篇文章,我會簡述我搭建最基本環境的過程並給出demo,然后再詳細地講一些配置。
在各個文章我會分別介紹,每篇都附有example,可以根據情況進行修改:
springmvc(本文)
springmvc+spring+hibernate+spring security
springmvc+spring+hibernate+spring security+spring oauth2
這篇文章就來介紹springmvc環境的搭建。
1. pom.xml
首先來看都需要加入哪些包,我使用maven來管理包的依賴。
<properties> <spring.version>4.0.4.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>tomcat</groupId> <artifactId>servlet-api</artifactId> <version>5.5.23</version> <scope>provided</scope> </dependency> <dependency> <groupId>tomcat</groupId> <artifactId>jsp-api</artifactId> <version>5.5.23</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.2.Final</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> </dependencies>
核心的包就是spring-webmvc,這個包導入之后會自動導入spring-core,spring-web等它的依賴包;
后面jstl、taglibs等包的導入是為了在jsp頁面中使用jstl等標簽;
commons-fileupload是為了文件上傳的需要,本demo中沒有上傳文件的部分,不過哪個網站能沒有上傳圖片呢?
hibernate-validator的導入是為了正常使用springmvc的valid,springmvc的valid只有接口沒有實現,如果要使用它的功能需要導入一個實現包,導入hibernate-validator就是為了這個目的,本文的demo里面沒有用到validation,所以只是為了運行基本demo,這個可以不導入;
jackson-mapper的導入是為了使用springmvc返回json的功能,對於這個功能springmvc也是只有接口沒有實現,如果不導入實現包,要返回json時會返回406錯誤。jackson-core包會作為依賴導入。
2. web.xml
springmvc和struts的一個機制上的區別就是,struts是一層一層的攔截器在過濾,springmvc是只有一個核心的Servlet,所以首先按照正常注冊Servlet的方法,在web.xml中注冊這個springmvc:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true" version="3.0"> <servlet> <servlet-name>spring-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>spring-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
springmvc還要做很多配置,那些配置在單獨的配置文件里,這個配置文件的默認位置就是在web.xml相同目錄下的<servlet-name>-servlet.xml,比如我的servlet-name配置的是spring-dispatcher,那么我的springmvc配置文件的默認位置就是web.xml同目錄下的spring-dispatcher-servlet.xml。
3. spring-dispatcher-servlet.xml
下一步就是配置springmvc,編輯WEB-INF/spring-dispatcher-servlet.xml:
<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.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="org.zhangfc.demo4springmvc.mvc"/> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/pages/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="2000000"/> </bean> <mvc:resources mapping="/static/**" location="/resources/"/> <mvc:default-servlet-handler /> </beans>
Springmvc的虛擬路徑與處理函數的映射,是通過annotation來設置的,這些類都在哪個包下面,就是那個component-scan屬性配置的,並設置支持annotation支持,springmvc的每一個處理函數都會返回一個String類型的變量(有的函數返回值就是String,有的返回值是一個對象,對象里有一個viewResolver需要的字符串),我這個設置就是設置一個前綴和后綴,舉個例子來說,對於函數返回的這個String,比如是abc,那么需要渲染的文件就是/pages/abc.jsp。
multipartResolver是上傳文件需要的配置,還是那句話,本demo中用不到,不過還是寫上,哪個項目里不需要上傳點東西呢。
最后一個屬性,是對靜態資源的映射,經過這個映射之后,要訪問/static/a.png時,實際訪問的就是/resources/a.png。
4. HomeController.java
下面來寫一個控制器,位置在上面component-scan配置的package下,springmvc用RequestMapping的annotation來指定虛擬路徑,把類這一級的和方法級的加在一起就是最終的虛擬路徑,看這段代碼:
@Controller @RequestMapping("/") public class HomeController { @RequestMapping("") public String home(){ return "index"; } @RequestMapping("/json") @ResponseBody public Map<String, String> json(){ Map<String, String> result = new HashMap<String, String>(); result.put("zhangsan", "hello"); result.put("lisi", "world"); result.put("wangwu", "nihao"); return result; } }
這兒類這個級別的RequestMapping的值是"/",home這個方法級別的呢值是空,兩個加起來就是"/",而json這個方法的RequestMapping是"/json",所以,當訪問的URL是"/"的時候,會調用home這個方法來處理,返回值是一個字符串index,還記得前面的viewResolver嗎,根據那個配置,這個方法執行完成之后會渲染/pages/index.jsp,所以在WEB-INF的同級目錄下創建pages目錄(也就是WEB-INF的兄弟目錄),再創建index.jsp,運行整個工程,訪問"http://localhost:8080/demo4springmvc/"得到的就是index.jsp,因為json方法有一個@ResponseBody的annotation,它的返回值直接給客戶端,所以訪問"http://localhost:8080/demo4springmvc/json"得到的就是json串:
{"lisi":"world","zhangsan":"hello","wangwu":"nihao"}
這是springmvc的最基本的demo,詳細的用法,我會各個框架整合在一起之后再寫。