框架-spring入門總結html
參考:java
http://www.cnblogs.com/heavenyes/p/3908546.htmlweb
http://www.cnblogs.com/heavenyes/p/3908717.htmlajax
springmvc是一個基於spring的mvc框架,各類優勢啥的用過就知道了.下面開始講HelloWorldController的實現.spring
1.開發環境搭建<導jar包+配置文件>apache
1.1 新建web工程springmvc,導入springmvc所需的jar包,由於springmvc是基於spring的,因此必須包含spring的jar包,我用的版本是spring3.1.0.導入如下jar包: json
1.2 配置web.xml tomcat
<!-- spring mvc配置 處理*.action和*.do請求 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 加載spring-servlet.xml配置文件,默認spring-servlet文件放在/WEB-INF目錄下,爲了便於管理,這裏放到了src目錄下 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- spring 配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml </param-value> </context-param>
1.3 spring-servlet.xml配置安全
springmvc啓動會去/WEB-INF/目錄下加載web.xml文件${servlet-name}-servlet.xml的配置文件,在web.xml文件中咱們配置的servlet-name爲spring,而且配置了spring-servlet.xml的路徑爲src目錄下.mvc
spring建議咱們把springmvc的配置放到${servlet-name}-servlet.xml,把service層的配置放到xxx-service.xml,把dao層的配置放到xxx-database.xml配置文件中,也就是把配置分散開來.下面就是spring-servlet.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- springmvc配置--> <!-- 自動掃描 --> <context:component-scan base-package="cn.springmvc.controller"/> <!-- 視圖解析類配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 若是返回的邏輯視圖名爲index,則視圖解析器會找到webroot/jsps/index.jsp -->
<property name="prefix"> <value>/jsps/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
1.4 配置applicationContext.xml,將spring的其餘配置放到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" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- spring 其餘配置 --> </beans>
ok,基本配置都完了,開始寫Controller.
2.HelloWorldController
controller是springmvc中負責處理請求的核心組件,等價於struts2中的Action.下面咱們開始編寫HelloWorldController.
package cn.springmvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller("helloWorldController") //--->beanName @RequestMapping(value="/hello") // controller的映射路徑 public class HelloworldController { @RequestMapping(value="/say")// 方法的映射路徑 public String sayHello(){ System.out.println("hello"); return "hello"; } }
如今就能夠發佈項目,而後輸入url訪問了:localhost:8080/springmvc/hello/say.action
如今感覺到springmvc的好處了吧,哈哈!簡潔的配置真讓人愛不釋手!
補充一點,struts2中的Action是prototype的,因此Action沒有線程安全問題.springmvc中的Controller默認是單例的,若是controller可能產生線程安全問題,能夠在Controller上加上@Scope("prototype")註解,告訴spring,每次請求都建立新的controller對象.
前面講了入門篇,如今來了解下springmvc的細節.mvc框架都有請求映射、數據綁定、請求處理、視圖解析這幾個過程,如今咱們來了解springmvc中的這些細節。
1.使用@RequestMapping來配置springmvc請求映射的url
springmvc中的請求映射有多種方式,固然用得最多的是基於註解的請求映射方式.開發中,咱們中使用@RequestMapping這個註解來表示controller和方法的url.@RequestMapping的源碼:
@Target({ElementType.METHOD, ElementType.TYPE}) // 註解能夠用在類和方法上 @Retention(RetentionPolicy.RUNTIME) // 註解在運行期有效 @Documented @Mapping public @interface RequestMapping {
String[] value() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {}; }
其中value屬性用來表示url,其餘屬性用於限定請求,也就是隻有知足某些條件才處理請求.
例如:@RequestMapping(method=RequestMethod.POST)
例如:限定Content-Type @RequestMapping(headers={"Content-Type=application/x-www-form-urlencoded"})
例如 : @RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")該方法僅處理ContentType=application/json的請求
例如:@RequestMapping(value = "/pets/{petId}", method =RequestMethod.GET, produces="application/json")該方法僅處理request中Accept包含application/json的請求
consumes和produces用的比較少,其餘幾個屬性比較常見.
@RequestMapping使用的實例:
@Controller @RequestMapping(value="/hello") public class HelloworldController { @RequestMapping(value="/say", //--> 請求url method={RequestMethod.POST}, // 請求方式爲 post headers={"Content-Type=application/x-www-form-urlencoded"}, // 必須包含ContentType=application/x-www-form-urlencoded,普通表單提交 params={"name=xxx","email=yyy"}) // 請求中必須包含 name=xxx&email=yyy //params={"name=xxx"})--->請求參數中必須包含 //headers={"Content-Type=application/x-www-form-urlencoded"}) --> 限制請求頭 public String sayHello(){ System.out.println("hello"); return "hello"; } }
2.使用@RequestParam和@ModelAttribute完成數據綁定
直白點說,就是如何接收request中的參數呢?springmvc的作法是在方法中定義形式參數,在調用方法時將request中參數賦值給對應的參數,經過註解來描述形參和request中參數的對應關係.
簡單例子,調用sayHello方法時,會傳一個name參數.程序中如何接收呢?
@RequestMapping(value="/say") public String sayHello(@RequestParam(value="nm",required=true,defaultValue="zzz")String name){ System.out.println("hello "+name); return "hello"; }
RequestParam有三個屬性:
若是request參數名稱和方法中形參名字同樣,代碼上能夠不聲明@RequestParam,框架會自動注入.
@RequestParam用來接收單個變量,若是咱們要接收的是一個對象呢?例如User(name,email)對象.這時咱們能夠用另一個註解@ModelAttribute.該註解的做用就是把request中參數綁定到一個對象上.
@RequestMapping(value="process") public String process(@ModelAttribute("user")User user){ System.out.println(user); return "index"; }
接收request的參數搞定了,那如何把數據放到request中,而後帶回頁面呢?這裏有兩種一種,一種就是經過ModelAndView對象,一種就是在方法中聲明參數.前一種方法在以後視圖解析時再說,這裏咱們將第二種方法.springmvc爲解決這個問題提供了一種很優雅的方法,在方法聲明Model或者Map的實例,把數據放到Model或者Map中(實際上Model中也是封裝了一個Map,只不過Model是以接口的形式提供的),框架在執行方法時會把Model和Map的實例方法request中,這樣就能夠在頁面上經過EL表達式取出頁面顯示了.這個過程在源碼分析那篇中有提到.
@RequestMapping(value="process") public String process(@ModelAttribute("user")User user,Model model){ System.out.println(user);
// 帶參數到頁面 jsp上${name}就能夠取值
model.addAttribute("name",user.getName());
return "index"; }
@RequestMapping(value="process2") public String process(@ModelAttribute("user")User user,Map<String,Object> result){ System.out.println(user);
// 帶參數到頁面 jsp上${name}就能夠取值
result.put("name",user.getName());
return "index"; }
3.結果頁面的返回
請求處理過程就是調用url對應的方法完成請求的處理的過程,在源碼分析篇詳細分析了這個過程。這裏咱們直接講結果頁面的返回.springmvc中提供了一個ModelAndView對象封裝結果視圖。以前的處理中咱們都是返回字符串形式的視圖名稱,這個字符串最終也會成爲ModelAndView對象中的viewName屬性,而後交由springmvc中結果視圖組件解析.
結果頁面返回主要有轉發和重定向兩種方式,這部分直接看代碼:
4. CharacterEncodingFilter
web.xml文件中配置編碼過濾器.GET方式的亂碼問題能夠設置tomcat的屬性.
<!-- CharacterEncodingFilter 過濾器解決POST方式亂碼問題 --> <filter> <filter-name>characterEncoding</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>*</url-pattern> </filter-mapping>
5.springmvc中的文件上傳和下載
springmvc文件上傳使用的是apache的fileupload組件,因此在springmvc中使用文件上傳時先要導入fileupload的jar包.還要在配置文件中配置文件上傳的Resolver.
<!-- 文件上傳配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8" /> <property name="maxUploadSize" value="10485760000" /> <property name="maxInMemorySize" value="40960" /> </bean>
文件上傳下載代碼示例:
頁面代碼:
<h4>單文件上傳</h4> <form action="${pageContext.request.contextPath }/file/upload.action" method="post" enctype="multipart/form-data"> <input type="file" name="file"/><br/> <input type="submit" value="上傳"> </form> <h4>多文件上傳</h4> <form action="${pageContext.request.contextPath}/file/uploads.action" method="post" enctype="multipart/form-data"> <input type="file" name="files"/><br/> <input type="file" name="files"/><br/> <input type="file" name="files"/><br/> <input type="submit" value="上傳"> </form>
6.springmvc中的json處理
講springmv與ajax的整合前,先講兩個註解.
@RequestBody:將http請求中的正文(請求體)賦值給應用了註解的參數,經過這個註解能夠直接獲取請求體的內容.須要注意的是:post請求才有請求體.
@ResponseBody:將數據做爲response的正文(響應體)返回.用這個註解能夠直接把方法的返回值寫到response對象中.一般用於完成ajax請求後服務端數據的返回.
先看兩個註解的應用代碼:
頁面代碼:
上面說了,@RequestBody和@ResponseBody的做用.接下來使用這兩個註解來處理json數據.下面程序的json轉換用的是fastjson.
用@ResponseBody返回json字符串.代碼以下:
/** * 用@ResponseBody返回json字符串 */ @RequestMapping(value="retJson") @ResponseBody public String retJson(@RequestParam("userId")Integer userId){ System.out.println("userId>>>>>>>>>>>>>>:"+userId); User user = new User(); // get User from db by userId user.setName("zhangsan"); user.setEmail("zhangsan@126.com"); // 返回json字符串 String json = JSON.toJSONString(user); return json; } 頁面代碼: function _retJson(){ var url = '${pageContext.request.contextPath}/ajax/retJson.action'; var param = {userId:1}; $.post(url,param,function(data){ alert(data); var user = eval("("+data+")"); alert(user.name+"..."+user.email); }); } <button onclick="_retJson();">retJson</button>
@RequestBody接收json字符串,@ResponseBody返回json字符串.
/** * 用@RequestBody接收json字符串,用@ResponseBody返回json字符串 */ @RequestMapping(value="doJson") @ResponseBody public String doJson(@RequestBody String jsonStr){ System.out.println("requestbody>>>>>>>>:"+jsonStr);
// json字符串 轉成對象 User user = JSON.parseObject(jsonStr,User.class); user.setName("_"+user.getName()); user.setEmail("_"+user.getEmail());
// 對象轉成json字符串 String retStr = JSON.toJSONString(user); return retStr; } 頁面代碼: function _doJson(){ // 獲取參數值,拼接json字符串 var name = $("#name").val(); var email = $("#email").val(); // json對象 var json = {name:name,email:email}; // json對象轉成json字符串 var jsonStr = JSON.stringify(json); /** * 也能夠手動拼接json字符串 var jsonStr = "{\"name\":\""+name+"\",\"email\":\""+email+"\"}"; */ var url = '${pageContext.request.contextPath}/ajax/doJson.action'; //由於發送的json字符串,要設置 Content-Type=application/json $.ajaxSetup({ contentType:'application/json;charset=UTF-8' }); // 發送請求 $.post(url,jsonStr,function(data){ alert(data); // json字符串轉json對象 var user = eval("("+data+")"); alert(user.name+"..."+user.email); }); } <input type="text" name="name" id="name"><br/> <input type="text" name="email" id="email"><br/> <button onclick="_doJson();">doJson</button>
@ResponseBody亂碼問題的解決,springmvc中StringHttpMessageConverter類默認用的是ISO8859-1編碼,因此用@ResponseBody返回中文時會產生亂碼問題.解決辦法是基於StringHttpMessageConverter寫一個Converter,該編碼爲UTF-8.
import java.nio.charset.Charset; import org.springframework.http.MediaType; import org.springframework.http.converter.StringHttpMessageConverter; public class MyStringConvert extends StringHttpMessageConverter{ private static final MediaType mt = new MediaType("text","html",Charset.forName("UTF-8"));// text/html;charset=utf-8 @Override protected MediaType getDefaultContentType(String t) { return mt; } }
聲明AnnotationMethodHandlerAdapter使用自定義的converter.在spring-servlet.xml中配置:
<!-- @ResponseBody返回中文亂碼問題 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters" > <bean class="cn.jack.util.MyStringConvert"></bean> </property> </bean>