SpringMVC基礎

普通方法搭建Spring MVC
"x" //跳轉界面
"redirect:x" //host發送變化
"forward:x" //跳轉至下個action
第一步:配置Web.xml文件


<!-- 定義SpringMVC前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置文件路徑 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<!-- 開始就啓動 -->
<load-on-startup>1</load-on-startup>
</servlet>


<!-- Springmvc攔截路徑 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>






第二步:配置對應的文件/WEB-INF/springmvc-config.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-4.2.xsd">
<!-- 配置的handle -->
<bean name="/hello" class="w.Action" />
<!-- 處理映射器將bean的name作爲url進行查找,需要在配置handle時指定name -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- 處理適配器,開發handle實現的接口 -->
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
</beans>




第三步:寫對應的java文件w.Action.java
public class Action implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
System.out.println("被調用");
// 創建模型
ModelAndView mv = new ModelAndView();
// 創建request請求
mv.addObject("message", "hello world");
// 創建邏輯視圖
mv.setViewName("/index.jsp");redirect:index.jsp//重定義
return mv;
}
}


註解法搭建:Spring MVC


第一步相同,第二步略微修改:


<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
">


<!-- 掃描 -->
<context:component-scan base-package="cn.anlemusic" />


<!-- 註冊detectAllHandlerMappings、detectAllHandlerAdapters配置方案,提供數據支持JSON、XML、@Valid、@DateTimeFormat、@NumberFormatannotation -->
<mvc:annotation-driven />


<!-- 使用默認的servlet來響應靜態文件,否則無法訪問JQ,404 -->
<mvc:default-servlet-handler />


<!-- 配置annotation類型的處理映射器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />


<!-- 配置annotation類型的處理映射器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />


<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
</beans>




第三步:cn.anlemusic.Action.java
//該類爲控制器類
@Controller
public class Action{
//設置URL
@RequestMapping(value = "/hello")
public ModelAndView hello() {
// TODO Auto-generated method stub
System.out.println("被調用");
// 創建模型
ModelAndView mv = new ModelAndView();
// 創建request請求
mv.addObject("message", "hello world");
// 創建邏輯視圖
mv.setViewName("/index.jsp");
return mv;
}
}


Spring MVC三種數據類型傳遞數據:
Model:arg0.asMap().put(String attributeName,Object AttributeValue);當然,其也有相應的addAttribute方法可以直接使用
ModelMap:addAttribute(String attributeName,Object AttributeValue);
ModelAndView:相對上述兩位參數,多了個setViewName方法用於存放視圖addObject(String attributeName,Object AttributeValue);


視圖配置器:通過視圖解析器,其他配置一樣
@Controller
public class Action{
@RequestMapping(value = "/hello")
public String hello(Model mv) { //此處可Model對象(是一個Spring MVC類型)、HttpServletRequest對象、HttpServletResponse對象、HttpSession對象等,Spring會將對象正確地傳遞給方法
// TODO Auto-generated method stub
System.out.println("被調用");
// 創建request請求
mv.addAttribute("message", "hello world");
return "x";
}
}
Spring MVC請求處理方法可能出現的參數類型(hello後面的括號裏):ServletRequest、HttpServletRequest、ServletResponse、HttpServletResponse、HttpSession、Locale、Reader、InputStream、OutputStream、Writer、Principal、Map
---Spring部分:HttpEntity<?>、WebRequest、NativeWebRequest、Model、ModelMap、RedirectAttributes、Errors、BindingResult、SessionStatus、UriComponentsBuilder
---註解類:@PathVariable、@MatrixVariable、@RequestParam、@RequestHeader、@RequestBody、@RequestPart
Spring MVC請求處理方法可返回的類型(return中):ModelAndView、Model、Map<k,v>、View、String、ResponseEntity、HttpEntity、Callable、void、DeferredResult


<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix">
<value>inde</value>
</property>
<!-- 後綴 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>




詳解DispatcherServlet


前端控制器第一件事做什麼?
    initMultipartResolver(context); //初始化上傳本地文件解析器
    initLocaleResolver(context); //初始化本地化解器
    initThemeResolver(context); //初始化主題解析器
    initHandlerMappings(context); //初始化處理器映射器,將請求映射到處理器
    initHandlerAdapters(context); //初始化處理器適配器
    initHandlerExceptionResolvers(context); //初始化異常解析器,有則解析
    initRequestToViewNameTranslator(context); //初始化請求到視圖名稱解析器
    initViewResolvers(context); //初始化視圖解析器
    initFlashMapManager(context); //初始化flash映射管理器


DispatcherServlet.properties配置文件指定了其使用的默認組件
本地化解器【one】:查找名爲localeResolver、類型爲LocaleResolver的bean作爲該類型組件,無則使用AcceptHeaderLocaleResolver
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver


主題解析器【one】:查找名爲themeResolver、類型爲ThemeResolver的bean作爲該類型組件,無則使用FixedThemeResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

處理器映射器(2個):默認detectAllHandlerMappings屬性爲true,根據類型匹配機制查找上下文以及Spring容器中所有類型爲HandlerMapping的bean。反之查找名爲handlerMapping、類型爲HandlerMapping的bean作爲該類型組件;如果前兩者都沒找到,則使用BeanNameUrlHandlerMapping
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping


處理器適配器(3個):默認detectAllHandlerAdapters屬性爲true,根據類型匹配機制查找上下文以及Spring容器中所有類型爲HandlerAdapters的bean。反之查找名爲handlerAdapters、類型爲HandlerAdapters的bean作爲該類型組件;如果前兩者都沒找到,則使用指定的三個類分別創建一個適配器,添加中適配器列表中
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter


異常解析器(3個):默認detectAllHandlerExceptionResolvers屬性爲true,根據類型匹配機制查找上下文以及Spring容器中所有類型爲HandlerExceptionResolvers的bean。反之查找名爲handlerException-Resolver、類型爲HandlerExceptionResolver的bean作爲該類型組件;如果前兩者都沒找到,則使用指定的三個類定義默認實現類
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver


視圖名稱解析器【one】:查找名爲viewNameTranslator、類型爲RequestToViewNameTranslator的bean作爲該類型組件,無則使用DefaultRequestToViewNameTranslator
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator


視圖解析器:默認detectAllViewResolvers屬性爲true,根據類型匹配機制查找上下文以及Spring容器中所有類型爲ViewResolver的bean。反之查找名爲ViewResolvers、類型爲ViewResolver的bean作爲該類型組件;如果前兩者都沒找到,則使用默認實現類InternalResourceViewResolver
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

flash映射管理器:查找名爲FlashMapManager、類型爲SessionFlashMapManager的bean作爲該類型組件用於管理FlashMap,即,數據默認儲存在HttpSession中
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager


文件上傳解析器【one】:查找名爲muliipartResolver、類型爲MuliipartResolver的bean作爲該類型組件,無則不會加載該類型組件






Spring MVC執行流程:
1、用戶向服務器請求,被Sping前端控制器DispatcherServlet截獲
2、DispatcherServlet對請求的URL進行解析,得到URI。再根據URI調用HandlerMapping獲得該Handler配置的所有相關對象,被封裝成HandlerExecutionChain對象返回
3、DispatcherServlet根據獲得的Handler選擇一個合適的HandlerAdapter
4、提取請求中的模型數據,開始執行Handler(Controller),在填充Handler的參與過程中,根據配置,Spring還會幫你做一些額外的工作。如:
消息轉換:將請求的Json、Xml等數據轉化爲對象,再將對象轉化爲指定的響應信息
數據轉換:數據類型轉換 String換成Integer
數據格式化:將字符串轉換爲字符串數字或者日期
數據驗證:長度、格式等,驗證結果存儲到BindingResult或Error中
5、Handler執行完成後,向DispatcherServlet返回一個ModelAndView對象,該ModelAndView對象中包含視圖名或視圖名和模型
6、根據返回的ModelAndView對象,選擇一個適合的ViewResolver(視圖解析器)返還給DispatcherServlet
7、ViewResolver結合Model和View來渲染視圖
8、將渲染的結果返回給客戶端






Spring從2.5開始之後,可以使用@Controller、@RequestMapping、@RequestParam、@ModelAttribute等註解。離不開Annotation的強大作用
Spring MVC常用註解:
用於參數綁定的註解有(四類):
request body部分 @RequestParam、@RequestBody
request uri部分 @PathVariable
request header部分  @RequestHeader、@CookieValue
attribute部分 @SessionAttributes、@ModelAttribute
一、@Controller:用於標記一個類、Spring使用掃描機制查找應用程序中所有基於註解的控制器類,分發器掃描該類中含有@RequestMapping註解的方法
二、@RequestMapping:可以用來註釋一個控制器類、這種情況下會被映射到控制器類的value+方法的value:
@Controller
@RequestMapping(value="/ss")
public class Action {
@RequestMapping(value="/s",name="/hello")
public String hello(Model mv) {
// TODO Auto-generated method stub
System.out.println("被調用");
// 創建request請求
mv.addAttribute("message", "hello world");
return "x";
}
}//需要訪問http://localhost:8080/w/ss/s兩道纔可訪問到
@RequestMapping支持的屬性:(除了name爲Sring類型、method爲RequestMethod[]類型,其他皆爲String[]類型)
value------------請求的URL,當僅僅這個屬性時可省略屬性名
name-------------別名,可代替value-雞肋の
method-----------處理那些HTTP請求(method=RequestMethod.POST)單選或多選method={RequestMethod.POST,RequestMethod.GET},默認任意(GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE)。
consumes---------提交內容類型consumes="application/json"
produces---------返回內容類型produces="application/json"
params-----------指定request中必須包含某些參數時,才讓該方法處理params="message=hello world" 前者爲名,後者爲參數值
headers----------request中必須包含某些指定的header值時,才能讓該方法處理請求headers="Referer=http://anlemusic.cn" 請求頭必須包含http://anlemusic.cn
path-------------在Servlet環境中只有uri路徑映射,支持路徑映射(/my.do),支持路徑模式(/my/*),支持相對路徑(edit.do),其他和value相同


三、@RequestParam:用於獲取前臺傳遞過來的參數
@RequestParam支持的屬性:(除了required爲boolean,且其默認值爲true,其他都爲String)
name-------------指定請求頭綁定的名稱
value------------別名,可代替value-雞肋の
required---------指定參數是否必須綁定
defaultValue-----如果沒有傳遞參數,使用的默認值
@RequestMapping(name = "s")
public String hello(@RequestParam(name="name",required=false,defaultValue="Root") String name) {
// TODO Auto-generated method stub
System.out.println(name);
return "x";
}//http://localhost:8080/w/s默認爲Root,http://localhost:8080/w/s?name=222爲222


四、@PathVariable:用於獲取請求Url中的動態數據
@PathVariable僅僅只支持一個屬性,就是value,類型爲String
@RequestMapping("{id}")//可更復雜的"/d/s/r/s{id}r"
public String hello(@PathVariable String id) {
// TODO Auto-generated method stub
System.out.println(id);
return "x";
}//http://localhost:8080/w/ssss得到路徑中的變量ssss




五、@RequestHeader:用於將請求頭信息區數據映射到功能處理方法參數上
@RequestHeader支持的屬性:(除了required爲boolean,且其默認值爲true,其他都爲String)
name-------------指定請求頭綁定的名稱
value------------別名,可代替value-雞肋の
required---------指定參數是否必須綁定
defaultValue-----如果沒有傳遞參數,使用的默認值
@RequestMapping("s")
public String hello(@RequestHeader("User-Agent") String id,
@RequestHeader(value = "Accept") String name) {
// TODO Auto-generated method stub
System.out.println(id);//Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
System.out.println(name);//text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
return "x";
}
Accept(客戶端支持的數據類型):text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language(客戶機的語言環境): zh-CN,zh;q=0.8
Accept-Encoding(客戶端支持數據壓縮格式):gzip, deflate, sdch, br
Content-Length(告訴瀏覽器回送數據的長度):624
Content-Type(數據類型):text/html;charset=ISO-8859-1
Date(訪問時間):Wed, 29 Nov 2017 09:47:43 GMT
Server(服務器類型):Apache-Coyote/1.1
Cache-Control(通過這個頭,控制緩存數據):max-age=0
Connection(請求完畢後關閉還是保存鏈接):keep-alive
Cookie(臨時文件.txt格式):JSESSIONID=05D051ED195617B923421688B494CA7F; __guid=111872281.2600476218320126500.1504973812308.449; monitor_count=202
Host(想訪問的服務器名稱):localhost:8080
User-Agent(客戶機的軟件環境):Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36


六、@CookieValue:用於獲取Cookie數據
@CookieValue支持的屬性(除了required爲boolean,且其默認值爲true,其他都爲String)
name-------------指定請求頭綁定的名稱
value------------別名,可代替value-雞肋の
required---------指定參數是否必須綁定
defaultValue-----如果沒有傳遞參數,使用的默認值
@RequestMapping("s")
public String hello(@CookieValue(value="JSESSIONID") String name) {
// TODO Auto-generated method stub
System.out.println(name);
return "x";
}//3DB6254F37BC7FB449BF2A889464036C


七、@SessionAttributes:指定Model中的那些屬性需要轉存到HttpSession中
@SessionAttributes支持的屬性:String[]、String[]、Class<?>[]
names------------Model中的屬性名稱
value------------別名,可代替names-雞肋の
types------------指定參數是否必須綁定
@SessionAttributes(names="name") //@SessionAttributes(names={"user","book"},types={user.class,book.class})
public class Action {
@RequestMapping("s")
public ModelAndView hello(ModelAndView mv) {
// TODO Auto-generated method stub${sessionScope.name }我是 
mv.addObject("name", "我是"); ${requestScope.name }我是 
mv.addObject("message", "r"); ${requestScope.message }r 
mv.setViewName("x");
return mv;
}
}

八、@ModelAttribute:會在@Controller每個方法執行之前調用此方法
@ModelAttribute支持的屬性僅僅只有一個,value---String類型


用法一、@ModelAttribute(value="")返回具體類的方法
@ModelAttribute("ansd") // ${requestScope.ansd }獲取到的值爲該方法返回值
public String begin() {
// TODO Auto-generated method stub
return "我是ansd";
}
@RequestMapping("s")
public ModelAndView hello(ModelAndView mv,HttpServletRequest request) {
// TODO Auto-generated method stub
mv.setViewName("x");
return mv;
}//http://localhost:8080/w/s執行之前會先運行@@ModelAttribute標記的方法


用法二、@ModelAttribute返回的void方法
@ModelAttribute
public void begin(Model model) {
// TODO Auto-generated method stub
model.addAttribute("name", "我是姓名"); //${requestScope.name }獲取到的值爲對應返回值
}


@RequestMapping("s")
public ModelAndView hello(ModelAndView mv,HttpServletRequest request) {
// TODO Auto-generated method stub
mv.setViewName("x");
return mv;
}//http://localhost:8080/w/s

用法三、@ModelAttribute返回具體類的方法
@ModelAttribute
public User begin(@RequestParam("name") String name) {
// TODO Auto-generated method stub
return find(name); //${requestScope.user.name }獲取user對象,Model屬性名爲該類型user
}

public User find(String name){
return User.setName("sd");
}


@RequestMapping("s")
public ModelAndView hello(ModelAndView mv,HttpServletRequest request) {
// TODO Auto-generated method stub
mv.setViewName("x");
return mv;
}//http://localhost:8080/w/s


用法四、@RequestMapping("x")@ModelAttribute("message")同時註釋一個方法時
@RequestMapping("x") //此處既是訪問url,也是視圖值
@ModelAttribute("message")
public String hello(ModelAndView mv,HttpServletRequest request) {
// TODO Auto-generated method stub
return "mode"; //返回mode的屬性值${requestScope.message }=mode
}


用法五、用其註釋一個方法的參數時
@ModelAttribute("user")
public User begin(Model model) {
// TODO Auto-generated method stub
User user = new User("來哥", "無敵");// <br> ${requestScope.user.pass }無敵
return user;
}


@RequestMapping("x")
public String hello(@ModelAttribute("user") User user) {
// TODO Auto-generated method stub
user.setName("樂哥");// <br> ${requestScope.user.name }樂哥 中途可以修改參數和新增參數
return "x";
}








信息轉換:通過修改處理器適配器,裝配其他類型
<!-- 配置annotation類型的處理器適配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!-- 將請求信息轉化爲字符串,可以讀取所有的媒體類型的請求信息。響應信息的媒體類型爲text/plain -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<!-- 繼承FormHttpMessageConverter,轉換XML數據 -->
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
<!-- 讀取二進制數據,泛型T,爲byte[]類型,可以讀取所有類型的請求信息。響應信息的媒體類型爲application/octet-stream -->
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<!-- 讀取text/xml、aoolication/xml對象。響應信息的媒體類型爲text/xml、aoolication/xml類型 -->
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
</list>
</property>
</bean>


#####################################################以上是默認裝配#####################################################


################################################以下還有一下很多可選配置################################################


<!-- 讀取BufferedImage對象,泛型T,爲BufferedImage對象,可以讀取所有類型的請求信息。響應信息的媒體類型爲BufferedImage類型 -->
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"></bean>
<!-- 支持讀取<String,?>、application/x-www-form-urlencoded類型,可以寫www-form-urlencoded及multipart/form-data類型的響應信息 -->
<bean class="org.springframework.http.converter.FormHttpMessageConverter"></bean>
<!-- 讀取Resource對象,泛型T,爲Resource對象,可以讀取所有類型的請求信息。響應信息的媒體類型爲application/octet-stream類型 -->
<bean class="org.springframework.core.io.Resource"></bean>
<!-- 讀取text/xml和application/xml類型,響應信息的媒體類型爲text/xml和application/xml類型 -->
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"></bean>
<!-- 通過JAXB2讀寫XML消息,泛型T爲Object對象,讀取text/xml和application/xml類型,響應信息的媒體類型爲text/xml和application/xml類型 -->
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<!-- 讀取application/json對象,泛型T,爲Object對象,可以讀取application/json類型的數據。響應信息的媒體類型爲application/json類型 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
<!-- 讀寫RSS種子消息,泛型T爲Channel類型,可以讀取application/rss+xml類型的數據。響應信息的類型爲application/rss+xml -->
<bean class="org.springframework.http.converter.feed.RssChannelHttpMessageConverter"></bean>
<!-- 讀寫RSS種子消息,泛型T爲Feed類型,可以讀取application/atom+xml類型的數據。響應信息的類型爲application/atom+xml -->
<bean class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter"></bean>


####################################################學渣專屬分界線######################################################
HttpMessageConverter<T>接口,將請求信息轉化爲一個對象
public abstract interface HttpMessageConverter<T>
{
  public abstract boolean canRead(Class<?> paramClass, MediaType paramMediaType); //讀取對象類型,將請求信息轉化爲clazz類型的對象
  
  public abstract boolean canWrite(Class<?> paramClass, MediaType paramMediaType); //寫入對象類型,將clazz類型寫入到響應流當中
  
  public abstract List<MediaType> getSupportedMediaTypes(); //返回當前轉換器支持的媒體類型
  
  public abstract T read(Class<? extends T> paramClass, HttpInputMessage paramHttpInputMessage) //將請求信息流轉換爲T類型
    throws IOException, HttpMessageNotReadableException;
 
  public abstract void write(T paramT, MediaType paramMediaType, HttpOutputMessage paramHttpOutputMessage) //將T類型對象寫入響應流當中
    throws IOException, HttpMessageNotWritableException;
}








Json調用
方法一、
HTML中
<span id="name"></span>
<br><span id="pass"></span>
<script type="text/javascript" src="js/jquerys.js"></script>
<script type="text/javascript">
$(function() {
$.ajax(
{
url:"${pageCountext.request.contextPath }/w/sw", //訪問路徑
dataType : "json", //返回的數據類型
type : "post", //請求方式post
contentType : "application/json", //發送的內容編碼格式
data : JSON.stringify({ //發送到服務器的數據
name : "姓名",
pass : "密碼"
}),
async : true, //默認異步,false則爲同步
success : function(data) { //成功後回調函數
$("#name").html(data.name); //數據可視化
$("#pass").html(data.pass);
},
error : function(data) {
alert(data);
}
});
});
</script>
@RequestBody:獲取到json數據後,將json數據設置到對應的User對象的屬性當中(該註解通常獲取的數據格式爲xml、json,返回數據也是這樣)
java中:
@RequestMapping("/sw")
//使用@RequestBody註解獲取到json數據後,將json數據設置到對應的User對象的屬性當中(該註解通常獲取的數據格式爲xml、json,返回數據也是這樣)
public void ss(@RequestBody User user, HttpServletResponse response)
throws IOException {
// TODO Auto-generated method stub
//Jackson庫主要類,
ObjectMapper mapper = new ObjectMapper();
//將user當作json輸出
System.out.println(mapper.writeValueAsString(user));
user.setName("了");
response.setContentType("text/html;charset=UTF-8");
//將此json輸出到客戶端,也可以利用json-lib包中的自定義工具JsonUtil.getJsonString4JavaPOJO(user),進行轉換,但因Json-lib不支持Spring,故無法接受Json,只能處理輸出
response.getWriter().print(mapper.writeValueAsString(user));
}


springmvc-config.xml中:注意添加這兩個
<!-- 註冊detectAllHandlerMappings、detectAllHandlerAdapters配置方案,提供數據支持JSON、XML、@Valid、@DateTimeFormat、@NumberFormatannotation -->
<mvc:annotation-driven />
<!-- 使用默認的servlet來響應靜態文件,否則無法訪問JQ,404 -->
<mvc:default-servlet-handler />




方法二、
springmvc-config.xml中:
<!-- 掃描 -->
<context:component-scan base-package="cn.anlemusic" />


<!-- 使用默認的servlet來響應靜態文件 -->
<mvc:default-servlet-handler />


<!-- 設置配置方案 -->
<mvc:annotation-driven>
<!-- 不使用默認的消息轉換器 -->
<mvc:message-converters register-defaults="false">
<!-- 配置Spring的轉換器 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter" />
<!-- 配置fastjson中實現HttpMessageConverter接口中的轉換器 -->
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- 這裏順序不能反,IE下會變成下載 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix">
<value>inde</value>
</property>
<!-- 後綴 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>


java中:將上述mapper.writeValueAsString(user)改爲JSONObject.toJSONString(user),其他不發生改變.


@ResponseBody:將Controller的方法返回的對象,通過適當的消息轉換器轉換爲指定格式後,寫入到Response對象的body數據區(該註解通常獲取的數據格式爲xml、json,返回數據也是這樣)
例:@ResponseBody
@RequestMapping(value = "/sw")
@ResponseBody
public Object ss() {
// TODO Auto-generated method stub
List<User> list = new ArrayList<User>();
list.add(new User("我來自數據庫", "name1"));
list.add(new User("我來自武漢", "name2"));
list.add(new User("我來自北京", "name3"));
return list;
}




<table id="User" border="1" style="border-collapse: collapse;">
<tr align="center">
<th>那麼</th>
<th>pass</th>
</tr>
</table>
<script type="text/javascript" src="js/jquerys.js"></script>
<script type="text/javascript">
$(function() {
$.post("${pageCountext.request.contextPath }/w/sw", null, function(
data) {
$.each(data, function() {
var tr = $("<tr align='center' />");
$("<td />").html(this.name).appendTo(tr);
$("<td />").html(this.pass).appendTo(tr);
$("#User").append(tr);
});
}, "json");
});
</script>








Xml調用


xml發送
$(function() {
var xmlData ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><user><name>helloXML</name><pass>您好</pass></user>";
$.ajax("${pageCountext.request.contextPath }/w/sendxml", {
type:"post",
contentType:"application/xml",
data:xmlData,
async:true
});
});


xml讀取
$.ajax("${pageCountext.request.contextPath }/w/read", {
dataType : "text",
type : "post",
async : true,
success : function(xml) {
var name = $("name", xml).text();
var pass = $("pass", xml).text();
var tr = $("<tr align='center' />");
$("<td />").html(name).appendTo(tr);
$("<td />").html(pass).appendTo(tr);
$("#User").append(tr);
},
error:function(){
alert("error");
}
});
<table id="User" border="1" style="border-collapse: collapse;">
<tr align="center">
<th>那麼</th>
<th>pass</th>
</tr>
</table>


User.java標記
@XmlRootElement//表示文檔的根元素
public class User {
private String name;


@Override
public String toString() {
return "User [name=" + name + ", pass=" + pass + "]";
}


public User(String name, String pass) {
super();
this.name = name;
this.pass = pass;
}


public User() {
super();
// TODO Auto-generated constructor stub
}


public String getName() {
return name;
}


@XmlElement//表示xml文檔的element元素
public void setName(String name) {
this.name = name;
}


public String getPass() {
return pass;
}


@XmlElement
public void setPass(String pass) {
this.pass = pass;
}


private String pass;


}


java中
@RequestMapping(value = "/sendxml")
// ajax發送來的數據通過@RequestBody負責轉換爲數據
public void send(@RequestBody User user) {
// TODO Auto-generated method stub
System.out.println(user.toString());// User [name=helloXML, pass=您好]
}


@RequestMapping(value = "/read")
public @ResponseBody
User ss() throws Exception {
// TODO Auto-generated method stub
// 通過JAXBContext的newInstance方法識別類
JAXBContext context = JAXBContext.newInstance(User.class);
// 創建一個Unmarshaller對象將 XML 數據反序列化爲新創建的 Java 內容樹的過程,並可在解組時有選擇地驗證 XML
// 數據。它針對各種不同的輸入種類提供各種重載的 unmarshal 方法。
Unmarshaller unmarshaller = context.createUnmarshaller();
// 從 File 解組
User user = (User) unmarshaller.unmarshal(new File(
"../webapps/w/read.xml"));
//User [name=helloXML, pass=您好]
System.out.println(user.toString());
//返回XML對象
return user;
}
<mvc:annotation-driven />中默認裝配了Jaxb2RootElementHttpMessageConverter










Spring MVC的標籤庫
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> //引入標籤庫,在spring-webmvc.jar中


標籤庫所有標籤:
form 渲染表單元素
modelAttribute form綁定的模型屬性名稱,默認爲command
commandName form綁定的模型屬性名稱,默認爲command
acceptCharset 定義服務器接收的字符編碼
cssClass 定義要應用到被渲染form元素的css類
cssStyle 定義要應用到被渲染form元素的css樣式
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
input 渲染<input type="text">元素
cssClass 定義要應用到被渲染input元素的css類
cssStyle 定義要應用到被渲染input元素的css樣式
cssErrorClass 定義要應用到被渲染input元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑




form和input的例子
@RequestMapping(value = "/s")
public String send(Model model) {
// TODO Auto-generated method stub
User user = new User("zhangsn", "來");
model.addAttribute("command", user);//model中添加屬性command,值爲User對象
return "x";
}
<form:form action="s" htmlEscape="">
賬號:<form:input path="name" />//默認自動填充
<br />
密碼:<form:input path="pass" />//這個就很牛X了,類似Struts中的ONGL,不過性質不一樣,一個是從棧堆取值,一個是利用Request
</form:form>




password 渲染<input type="password">元素
cssClass 定義要應用到被渲染password元素的css類
cssStyle 定義要應用到被渲染password元素的css樣式
cssErrorClass 定義要應用到被渲染password元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
showPassword 是否應該顯示密碼,默認false不顯示,true將會顯示遮蓋的密碼
hidden 渲染<input type="hidden">元素(隱藏的域)
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
textarea 渲染textarea元素
cssClass 定義要應用到被渲染textarea元素的css類
cssStyle 定義要應用到被渲染textarea元素的css樣式
cssErrorClass 定義要應用到被渲染textarea元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
checkbox 渲染<input type="checkbox">元素
cssClass 定義要應用到被渲染checkbox元素的css類
cssStyle 定義要應用到被渲染checkbox元素的css樣式
cssErrorClass 定義要應用到被渲染checkbox元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
lable 要作爲label被渲染的複選框的值




checkbox例
private Boolean read;
private List<String> value;//Checkbox.java
@RequestMapping(value = "/s")
public String send(Model model) {
// TODO Auto-generated method stub
Checkbox checkbox = new Checkbox();
checkbox.setRead(true);// 添加了個值Read=true
List<String> list = new ArrayList<String>();
list.add("a");
list.add("c");// 添加了一組值
checkbox.setValue(list);
model.addAttribute("command", checkbox);// 至前臺,發現value有的則默認鉤上了,反之沒有
return "x";
}
<form:form action="s" htmlEscape="">
<form:checkbox path="value" label="樂哥" value="a" /> //嘟嘟,發現在value中有a,勾上
<form:checkbox path="value" label="來哥" value="b" /> //嘟嘟,發現在value中沒有a,不勾上
<form:checkbox path="value" label="我是無敵" value="c" /> //嘟嘟,發現在value中有c,勾上
<form:checkbox path="read" value="true" /> //嘟嘟,發現在value中有true,勾上
</form:form>




checkboxes 渲染<input type="checkbox">元素
cssClass 定義要應用到被渲染checkboxes元素的css類
cssStyle 定義要應用到被渲染checkboxes元素的css樣式
cssErrorClass 定義要應用到被渲染checkboxes元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
items 用於生成checkbox元素的對象的Collection、Map或者Array
itemLable item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個checkbox元素提供label
itemValue item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個checkbox元素提供value
delimiter 定義兩個input元素之間的分隔符,默認沒有分隔符




checkboxes例一:lable和value相同的情況
private List<String> value;//Checkbox.java
@RequestMapping(value = "/s")
public String send(Model model) {
// TODO Auto-generated method stub
Checkbox checkbox = new Checkbox();
//已經選擇好的
List<String> list = new ArrayList<String>();
list.add("事");
list.add("啊");
checkbox.setValue(list);
//頁面提供的選擇
List<String> couList = new ArrayList<String>();
couList.add("來");
couList.add("搞");
couList.add("事");
couList.add("情");
couList.add("啊");
model.addAttribute("command", checkbox);
model.addAttribute("commands", couList);
return "x";
}
<form:form action="s" modelAttribute="command"> //默認的command
<form:checkboxes items="${commands }" path="value" /> //循環體commands,獲取command.value
</form:form>




checkboxes例二:lable和value不相同的情況
HTML與上述一樣
@RequestMapping(value = "/s")
public String send(Model model) {
// TODO Auto-generated method stub
Checkbox checkbox = new Checkbox();
//已經選擇好的
List<String> list = new ArrayList<String>();
list.add("1");
list.add("3");
checkbox.setValue(list);
//頁面提供的選擇
Map<String,Object> couList = new HashMap<String,Object>();
couList.put("1", "來啊");
couList.put("2", "絕對");
couList.put("3", "不怕");//MAP的value變成了lable,key成了值
couList.put("4", "ni");
model.addAttribute("command", checkbox);
model.addAttribute("commands", couList);
return "x";
}


checkboxes例三:lable和value不相同的情況,不使用Map
private Integer id;
private String name; //Checkbox.java
private List<Checkbox> che; //Checkboxee.java
<form:form action="s" modelAttribute="command">
<form:checkboxes items="${commands }" path="che" itemLabel="name" itemValue="id" />
</form:form>
@RequestMapping(value = "/s")
public String send(Model model) {
// TODO Auto-generated method stub
Checkboxee checkboxee = new Checkboxee(); //選擇好的
Checkbox checkbox = new Checkbox(1, "開發部");
List<Checkbox> checkboxlist = new ArrayList<Checkbox>();
checkboxlist.add(checkbox);
checkboxee.setChe(checkboxlist); //添加選擇好了的
List<Checkbox> list = new ArrayList<Checkbox>();//全部
list.add(checkbox);
list.add(new Checkbox(2, "什麼部門"));
list.add(new Checkbox(3, "喜羊羊部門"));
list.add(new Checkbox(4, "懶羊羊部門"));
model.addAttribute("command", checkboxee);
model.addAttribute("commands", list);
return "x";
}




radiobutton 渲染<input type="radio">元素
cssClass 定義要應用到被渲染radiobutton元素的css類
cssStyle 定義要應用到被渲染radiobutton元素的css樣式
cssErrorClass 定義要應用到被渲染radiobutton元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
lable 要作爲label被渲染的複選框的值 //用法和多選框一樣,不再贅述
radiobuttons 渲染<input type="radio">元素
cssClass 定義要應用到被渲染radiobuttons元素的css類
cssStyle 定義要應用到被渲染radiobuttons元素的css樣式
cssErrorClass 定義要應用到被渲染radiobuttons元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
items 用於生成checkbox元素的對象的Collection、Map或者Array
itemLable item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個radio元素提供label
itemValue item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個radio元素提供value
delimiter 定義兩個input元素之間的分隔符,默認沒有分隔符 //用法和多選框一樣,利用map可達到分離lable和value,不再贅述
select 渲染一個選擇元素
cssClass 定義要應用到被渲染select元素的css類
cssStyle 定義要應用到被渲染select元素的css樣式
cssErrorClass 定義要應用到被渲染select元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
path 要綁定屬性的路徑
items 用於生成select元素的對象的Collection、Map或者Array
itemLable item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個select元素提供label
itemValue item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個select元素提供value
option 渲染一個可選元素
cssClass 定義要應用到被渲染option元素的css類
cssStyle 定義要應用到被渲染option元素的css樣式
cssErrorClass 定義要應用到被渲染option元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
options 渲染可選元素列表
cssClass 定義要應用到被渲染option元素的css類
cssStyle 定義要應用到被渲染option元素的css樣式
cssErrorClass 定義要應用到被渲染option元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
items 用於生成select元素的對象的Collection、Map或者Array
itemLable item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個option元素提供label
itemValue item屬性中定義的Collection、Map或者Array中的對象屬性,爲每個option元素提供value
errors 在span元素中渲染字段錯誤
cssClass 定義要應用到被渲染errors元素的css類
cssStyle 定義要應用到被渲染errors元素的css樣式
cssErrorClass 定義要應用到被渲染errors元素的css類,如果boound屬性中包含錯誤,則覆蓋cssClass屬性值
delimiter 定義兩個input元素之間的分隔符,默認沒有分隔符
path 要綁定屬性的路徑




errors例:
private String name;
private Integer id;
private String pass;//User.java


public class UserValidator implements Validator {


@Override
public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return User.class.equals(arg0);
}


@Override
public void validate(Object arg0, Errors arg1) {
// TODO Auto-generated method stub
ValidationUtils.rejectIfEmpty(arg1, "id", null, "id爲空");
ValidationUtils.rejectIfEmpty(arg1, "name", null, "name爲空");
ValidationUtils.rejectIfEmpty(arg1, "pass", null, "pass爲空");
}


}//UserValidator.java驗證java


@RequestMapping(value = "/ss")
public String send(Model model) {
// TODO Auto-generated method stub
User user = new User("ss", 22, "rr");
model.addAttribute("user", user);
return "MyJsp";
}


@InitBinder
public void initBinder(DataBinder binder) {
//設置驗證類
binder.setValidator(new UserValidator());
}
@RequestMapping(value = "/s")
public String sends(@Validated User user,Errors errors) {
// TODO Auto-generated method stub
if(errors.hasFieldErrors()){
return "MyJsp";//出現錯誤跳轉至MyJsp.jsp
}
System.out.println("對了");
return "index";
}//action.java
<form:form modelAttribute="user" method="post" action="s">


<form:input path="id" />
<form:errors path="id" />
<br />
<form:input path="name" />
<form:errors path="name" />
<br />
<form:input path="pass" />
<form:errors path="pass" />
<br />
<input type="submit" value="提交" />
</form:form>//MyJsp.jsp,成功則跳轉到index.jsp,此頁面爲空




國際化


1、messageSource
<!-- messageSource國際化,在SpringMVC中,不直接使用java.util.ResourceBundle,而是利用messageSource的bean告訴SpringMVC的國際化文件儲存地址 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message</value>
<value>fkit</value>
</list>
</property>
</bean>


2、localeResolver
用戶選擇語言區域時,可通過三種方法AcceptHeaderLocaleResolver、SessionLocaleResolver、CookieLocaleResolver


3、message標籤
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
message標籤屬性:
argument 標籤的參數,可以是字符串、數組、或者對象
argumentSeparator 用來分隔該標籤參數的字符
code 獲取消息的key
htmlEscape Boolean值,表示被渲染的值是否應該進行HTML轉義
javaScriptEscape Boolean值,表示被渲染的值是否應該進行JavaScript轉義
message MessageSourceResolvable參數
scope 保存var屬性中定義的變量作用範圍域
text 如果code屬性不存在,所顯示的默認文本
var 用於保存消息的變量




native2ascii命令處理文件:native2ascii -[options] [inputfile [outputfile]]
options命令開關--可選-encoding encoding_name:將轉換爲指定編碼,-encoding utf8(gbk、ISO8859-1)、-reverse:將Unicode編碼轉換爲本地或者指定編碼,不指定則本地編碼
inputfile輸入的文件全名
outputfile輸出的文件全名
一、AcceptHeaderLocaleResolver國際化


第一步創建文件
message_en_US.properties username=administrator
message_zh_CN.properties username=\uFFFD\uFFFD\uFFFD\uFFFD\u0531
分別爲不同語言的文件,後者需要利用native2ascii轉碼


第二步顯示語言
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> 加入spring-tags
<spring:message code="username" />
訪問文件中的國際化內容,發現報錯java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
因爲沒有配置ContextLoaderListener導致的,這個地方書上錯太多了,卡頓了好幾天


打開web.xml配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


<!-- 定義SpringMVC前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置文件路徑 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>//相對之前改了名稱,因爲ContextLoaderListener默認配置爲這個地方,作者就將就下
</init-param>
<!-- 開始就啓動 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Springmvc攔截路徑 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


applicationContext中
<!-- 國際化 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 國際化資源文件 -->
<!-- basenam只有一組文件時候,多組使用basenames.value用來指定文件以XXX開頭 -->
<property name="basenames" value="classpath:message" />//No message found under code 'loginname' for locale 'zh_CN'.錯誤因爲沒有加classpath:書上都TM是騙人的
</bean>


<!-- 國際化操作攔截器如果採用基於(session/Cookie)則必須配置 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>


<!-- AcceptHeaderLocaleResolver配置,默認可省略 -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />






二、SessionLocaleResolver國際化
applicationContext配置文件
<!-- 國際化 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 國際化資源文件 -->
<!-- basenam只有一組文件時候,多組使用basenames.value用來指定文件以XXX開頭 -->
<property name="basenames" value="classpath:message" />
</bean>


<!-- 國際化操作攔截器如果採用基於(session/Cookie)則必須配置 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>


<!-- SessionLocaleResolver配置,默認可省略 -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />




java文件
@RequestMapping("req")
public String login(String loc, HttpSession session, Model model) {
// TODO Auto-generated method stub
if (loc != null) {
// 如果是中國,啓動中國配置文件
if (loc.equals("zh_CN")) {
Locale locale = new Locale("zh", "CN");
session.setAttribute(
SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,
locale);
// 如果是美國,啓動美國配置文件
} else if (loc.equals("en_US")) {
Locale locale = new Locale("en", "US");
session.setAttribute(
SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,
locale);
} else {
session.setAttribute(
SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,
LocaleContextHolder.getLocale());
}
}
return "w";
}


html
<a href="req?loc=en_US">英文</a>
<br />
<a href="req?loc=zh_CN">中文</a>
<spring:message code="loginname"></spring:message>
<spring:message code="password"></spring:message>
<spring:message code="submit"></spring:message>
<spring:message code="welcome"></spring:message>
<spring:message code="title"></spring:message>
<spring:message code="username"></spring:message>


message_en_US.properties
loginname=Login name
password=Password
submit=Submit
welcome=Welcome {0} access fkIT
title=Login Page
username=administrator


message_zh_CN.properties
loginname=\u7528\u6237\u540D\uFF1B
password=\u5BC6\u7801\uFF1B
submit=\u63D0\u4EA4\uFF1B
welcome=\u6B22\u8FCE {0} \u6765\u5230\u5927\u54E5\u7684\u4E50\u56ED
title=\u9875\u9762\u6807\u9898
username=\u7528\u6237\u540D






三、CookieLocaleResolver國際化


<!-- 國際化 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 國際化資源文件 -->
<!-- basenam只有一組文件時候,多組使用basenames.value用來指定文件以XXX開頭 -->
<property name="basenames" value="classpath:message" />
</bean>


<!-- 國際化操作攔截器如果採用基於(session/Cookie)則必須配置 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>


<!-- SessionLocaleResolver配置,默認可省略 -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />


/** 一定要經過SpringMVC攔截器,不能直接訪問靜態資源 **/
@RequestMapping(value = "/{formName}")
public String exe(@PathVariable String formName) {
// TODO Auto-generated method stub
return formName;
}


@RequestMapping("req")
public String login(String loc, HttpServletRequest request,
HttpServletResponse response, Model model) {
// TODO Auto-generated method stub
if (loc != null) {
// 如果是中國,啓動中國配置文件
if (loc.equals("zh_CN")) {
Locale locale = new Locale("zh", "CN");
(new CookieLocaleResolver()).setLocale(request, response,
locale);
// 如果是美國,啓動美國配置文件
} else if (loc.equals("en_US")) {
Locale locale = new Locale("en", "US");
(new CookieLocaleResolver()).setLocale(request, response,
locale);
} else {
(new CookieLocaleResolver()).setLocale(request, response,
LocaleContextHolder.getLocale());
}
}
return "w";
}


html
<a href="req?loc=en_US">英文</a>
<br />
<a href="req?loc=zh_CN">中文</a>
<spring:message code="loginname"></spring:message>
<spring:message code="password"></spring:message>
<spring:message code="submit"></spring:message>
<spring:message code="welcome"></spring:message>
<spring:message code="title"></spring:message>
<spring:message code="username"></spring:message>


message_en_US.properties
loginname=Login name
password=Password
submit=Submit
welcome=Welcome {0} access fkIT
title=Login Page
username=administrator


message_zh_CN.properties
loginname=\u7528\u6237\u540D\uFF1B
password=\u5BC6\u7801\uFF1B
submit=\u63D0\u4EA4\uFF1B
welcome=\u6B22\u8FCE {0} \u6765\u5230\u5927\u54E5\u7684\u4E50\u56ED
title=\u9875\u9762\u6807\u9898
username=\u7528\u6237\u540D




Spring MVC的數據轉換


系統默認的數據轉換
<!-- 定義一個數據轉換的ConversionService,內置基礎對象的轉換,String、Number、Array、Collection、Map、Properties、Object之間的轉換器 -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean" />


自定義類型轉換器
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="cn.anlemusic.Book" />
</list>
</property>
</bean>


類型轉換的核心接口:ConversionService
// 判斷是否可以將一個java類轉換爲另個java類
@Override
public boolean canConvert(Class<?> arg0, Class<?> arg1) {
// TODO Auto-generated method stub
return false;
}


// 需要轉換的類將以成員變量的方式出現,分別代表需要轉換的信息和上下文性信息
@Override
public boolean canConvert(TypeDescriptor arg0, TypeDescriptor arg1) {
// TODO Auto-generated method stub
return false;
}


// 將原類型對象轉換爲目標對象
@Override
public <T> T convert(Object arg0, Class<T> arg1) {
// TODO Auto-generated method stub
return null;
}


// 將對象從源類型對象轉換爲目標對象
@Override
public Object convert(Object arg0, TypeDescriptor arg1, TypeDescriptor arg2) {
// TODO Auto-generated method stub
return null;
}


在org.springframework.core.convert.converter包中定義了三種類型的轉換器接口
Converter<S, T>接口
  public abstract T convert(S paramS);
負責將S類型對象轉換爲T對象


ConverterFactory<S, R>接口
  public abstract <T extends R> Converter<S, T> getConverter(Class<T> paramClass);
負責將S對象轉換爲R對象及其子類對象(例如:String轉換爲Number對象及其下面子類對象:Integer、Double等對象)


GenericConverter接口
  public abstract Set<ConvertiblePair> getConvertibleTypes();
ConvertiblePair封裝了源對象類型和目標對象類型 ConvertiblePair(Class<?> sourceType, Class<?> targetType)
  public abstract Object convert(Object paramObject, TypeDescriptor sourceTypeDescriptor1, TypeDescriptor targetTypeDescriptor2);
轉入的參數、需要轉換類型的上下文信息、轉換後類型的上下文信息,此方法可以利用這些上下文信息進行類型轉換的工作






數據轉換流程
將String轉換爲date:
方法一、
第一步:html中
<form action="re" method="post">
<input type="text" name="loginname"><br />
<input type="text" name="date"><br />
<input type="submit" value="提交">
</form>


第二步:xml中(裝配的一定要放在<mvc:annotation-driven />之前)
<!-- 裝配自定義類型轉換器 -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 定義一個數據轉換的ConversionService,內置基礎對象的轉換,String、Number、Array、Collection、Map、Properties、Object之間的轉換器 -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="cn.anlemsuic.DateString" p:datePattern="yyyy-MM-dd" />
</list>
</property>
</bean>


第三步:cn.anlemsuic.DateString中
public class DateString implements Converter<String, Date> {
private String datePattern;


public void setDatePattern(String datePattern) {
this.datePattern = datePattern;
}
@Override
public Date convert(String date) {
// TODO Auto-generated method stub
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
return dateFormat.parse(date);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("日期轉換失敗");
return null;
}
}
}


第四步:java中
@RequestMapping("re")
public String login(@ModelAttribute User user, Model model) {
// TODO Auto-generated method stub
System.out.println(user.toString());
model.addAttribute("user", user);
return "w";
}


第五步:jsp中
${requestScope.user.loginname } 111 
<br /> ${requestScope.user.date } Fri Oct 21 00:00:00 CST 2016 
<br />




方法二、使用@InitBinder添加定義編輯器轉換數據
第一步:
/** 編輯器類 **/
public class Editor extends PropertyEditorSupport{
@Override
public void setAsText(String text) throws IllegalArgumentException {
// TODO Auto-generated method stub
//用給定的模式和默認語言環境的日期格式符號構造 SimpleDateFormat
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
//從給定字符串的開始解析文本,以生成一個日期。該方法不使用給定字符串的整個文本
Date date = dateFormat.parse(text);
//設置(或更改)將被編輯的對象。 
setValue(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}


第二步:html中
<form action="re" method="post">
<input type="text" name="loginname"><br />
<input type="text" name="date"><br />
<input type="submit" value="提交">
</form>


第三步:java中
// 控制器初始化時註冊屬性編輯器,該註解會在控制器初始化是註冊屬性編輯器
@InitBinder
public void initBinder(WebDataBinder binder) {
// 註冊自定義編輯器
binder.registerCustomEditor(Date.class, new Editor());
}
@RequestMapping("re")
public String login(@ModelAttribute User user, Model model) {
// TODO Auto-generated method stub
model.addAttribute("user", user);
return "w";
}


第四步:jsp中
${requestScope.user.loginname } 111 
<br /> ${requestScope.user.date } Fri Oct 21 00:00:00 CST 2016 
<br />


或者
第一步:/** 編輯器類 **/和上述相同
第二步:
/** 該類用於註冊全局自定義編輯器轉換數據 **/
public class DateBinding implements WebBindingInitializer {
@Override
public void initBinder(WebDataBinder arg0, WebRequest arg1) {
// TODO Auto-generated method stub
// 註冊自定義編輯器
arg0.registerCustomEditor(Date.class, new Editor());
}
}
第三步:xml(不可配置<mvc:annotation-driven />、<mvc:default-servlet-handler />)
<!-- 通過AnnotationMethodHandlerAdapter裝配自定義編輯器 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="WebBindingInitializer">
<bean class="cn.anlemsuic.DateBinding" />
</property>
</bean>
第四步:java中
@RequestMapping("re")
public String login(@ModelAttribute User user, Model model) {
// TODO Auto-generated method stub
System.out.println(user.toString());
model.addAttribute("user", user);
return "w";
}


多種轉換器的優先順序:@InitBinder裝配的自定義編輯器>通過ConversionService裝配的自定義轉換器>通過WebBindingInitializer接口定義的全局自定義編輯器






Spring MVC 格式化
上述講述了String轉換到Date轉換,即Object至Object之間的轉換。利用了Converter。下面講述格式化和數據的解析,即Object與String之間的轉換。利用了Formatter。


Pringer接口
public abstract String print(T paramT, Locale paramLocale);
將T類型的對象根據Locale信息已某種格式化進行打印顯示


Parser接口
public abstract T parse(String paramString, Locale paramLocale) throws ParseException;
根據Locale信息解析字符串到T類型對象


Formatter接口
public abstract interface Formatter<T> extends Printer<T>, Parser<T>{} 繼承上述兩個接口


FormatterRegistrar接口
public abstract void registerFormatters(FormatterRegistry paramFormatterRegistry);
註冊格式化轉換器


AnnotationFormatterFactory<A extends Annotation>接口
  public abstract Set<Class<?>> getFieldTypes();
  註解A的應用範圍
  public abstract Printer<?> getPrinter(A paramA, Class<?> paramClass);
  根據A獲取特定屬性類型的Printer
  public abstract Parser<?> getParser(A paramA, Class<?> paramClass);
  根據A獲取特定屬性類型的Parser


實例一、利用Formatter格式化數據


第一步:html中
<form action="re" method="post">
<input type="text" name="loginname"><br />
<input type="text" name="date"><br />
<input type="submit" value="提交">
</form>


第二步:java中
public class DateFormatter implements Formatter<Date> {
// 日期格式化對象
private SimpleDateFormat dateFormat;
public DateFormatter() {
// TODO Auto-generated constructor stub
super();
}
// 日期類型模板 如:yyyy-MM-dd
public SimpleDateFormat getDateFormat() {
return this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
// 顯示Formatter<T>的類型對象
@Override
public String print(Date arg0, Locale arg1) {
// TODO Auto-generated method stub
return dateFormat.format(arg0);
}
// 解析文本字符串,返回一個Formatter<T>類型對象
@Override
public Date parse(String arg0, Locale arg1) throws ParseException {
// TODO Auto-generated method stub
try {
return getDateFormat().parse(arg0);
} catch (Exception e) {
// TODO: handle exception
throw new IllegalArgumentException();
}
}
}


第三步:註冊xml(不可配置<mvc:annotation-driven />、<mvc:default-servlet-handler />)
<!-- 裝配自定義格式化轉換器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 格式化轉換器 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="cn.anlemsuic.DateFormatter" />
</list>
</property>
</bean>
或者自帶的轉換對象,無需自己寫java
<!-- 裝配自定義格式化轉換器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 格式化 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="org.springframework.format.datetime.DateFormatter"
p:pattern="yyyy-MM-dd" />
</list>
</property>
</bean>
第四步:jsp中
${requestScope.user.loginname } 111 
<br /> ${requestScope.user.date } Fri Oct 21 00:00:00 CST 2016 
<br />






在org.springframework.format中,提供了三個用於數字對象格式化的實現類:
NumberFormatter:用於數字類型對象的格式化
CurrencyFormatter:用於貨幣類型的格式化
PercentFormatter:用於百分數數字類型對象格式化


以上都是過時的硬編碼,下面介紹註解法格式化數據
在org.springframework.format.annotation包下定義了兩個格式化的註解類型:
@NumberFormat:可對數字類型的屬性進行標註,pattern類型爲String,使用自定義的數字格式化串。style類型爲三種類型:(NumberFormat.CURRENCY)貨幣類型、(NumberFormat.NUMBER)正常數字類型、(NumberFormat.PERCENT)百分數類型
@DateTimeFormat:可對java.until.Date、java.util.Calendar等時間類型進行註解
ios類型DateTimeFormat.ISO.DATE(yyyy-MM-dd)、TIME(hh:mm:ss .SSSZ)、DATE_TIME(yyyy-MM-dd hh:mm:ss .SSSZ)、NONE(不使用ISO格式的時間)
pattern類型爲String,使用自定義的時間格式化字符串(如:yyyy-MM-dd hh:mm:ss)
style類型爲String,指定時間格式,S(短日期樣式)、M(中日期樣式)、L(長日期樣式)、F(完整日期樣式)、-(忽略日期樣式)


乾貨說完了,來點溼例:
html
<H3>測試格式化</H3>
<form action="re" method="post">
日期:<input type="text" name="rq"><br /> 
整數:<input type="text" name="zs"><br /> 
百分數<input type="text" name="bfb"><br /> 
貨幣:<input type="text" name="hb"><br />
<input type="submit" value="提交">
</form>


Dao.java
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date rq;
@NumberFormat(style = Style.NUMBER,pattern="#,###")
private int zs;
@NumberFormat(style = Style.PERCENT)
private double bfb;
@NumberFormat(style = Style.CURRENCY)
private double hb;


Action.java
@RequestMapping("re")
public String login(@ModelAttribute Dao dao, Model model) {
// TODO Auto-generated method stub
System.out.println(dao.toString());
model.addAttribute("dao", dao);
return "w";
}


jsp
${requestScope.dao.rq }=Sun Feb 03 00:00:00 CST 2013 
<br /> ${requestScope.dao.zs }=232
<br /> ${requestScope.dao.bfb }=0.23 
<br /> ${requestScope.dao.hb }=2.3333 




Spring MVC 數據校驗(Validation校驗框架和JSR303校驗功能)


Spring的校驗框架在org.springframework.validation包裏
Validator接口:最重要的接口,擁有兩個方法
  public abstract boolean supports(Class<?> paramClass);
  //該校驗器能對clazz類型的對象進行校驗
  public abstract void validate(Object paramObject, Errors paramErrors);
//對paramObject(傳遞過來的參數)進行校驗,並將錯誤信息記錄在paramErrors中


Errors接口:Spring用來存放錯誤信息
一個error包含兩個對象
FieldError對象:表示與被校驗的對象中的某個屬性相關的錯誤
ObjectError對象:Error的Object對象


ValidationUtils接口
Spring提供一個關於校驗的工具類,它提供了多個給Error對象保存錯誤的方法


LocalValidatorFactoryBean方法位於org.springframework.validation.beanvalidation包中,該方法實現了ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean(Validation校驗框架和JSR303校驗功能的)接口
只要在Spring容器中定義一個LocalValidatorFactoryBean,即可將其注入到需要數據校驗的bean中:




Validation校驗框架(其實上面講到error時有,標籤):
第一步:jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<jsp:useBean id="users" class="cn.anlemusic.Users" scope="request" />
<form:form modelAttribute="users" method="post" action="re">
<form:input path="name" />
<form:errors path="name" cssStyle="color:red" />
<br />
<form:input path="pass" />
<form:errors path="pass" cssStyle="color:red" />
<br />
<input type="submit" value="提交" />
</form:form>


第二步:測試類java
//實現Spring的Validator的接口
@Repository("UsersVali")
public class UsersVali implements Validator {
// 能對clazz類型進行校驗
@Override
public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
// User指定Class參數所表示的類或者接口是否相同
return Users.class.isAssignableFrom(clazz);
}
// 對目標類target進行校驗,並將校驗錯誤記錄在errors中
@Override
public void validate(Object target, Errors errors) {
// TODO Auto-generated method stub
/** 使用ValidationUtils工具的rejectIfEmpty方法來對它們進行驗證,如果爲null或者爲空則拒絕驗證通過 **/
// errors錯誤信息,錯誤對象,錯誤代碼,錯誤提示信息
ValidationUtils.rejectIfEmpty(errors, "name", null, "賬號不爲空");
ValidationUtils.rejectIfEmpty(errors, "pass", null, "密碼不爲空");
Users users = (Users) target;
if (users.getName().length() > 10) {
// 錯誤的地方,錯誤信息
errors.rejectValue("name", null, "賬號超過十位數");
}
if (users.getPass().length() < 6 && !users.getPass().equals("")
&& users.getPass() != null) {
errors.rejectValue("pass", null, "密碼不小於6位數");
}
}
}


第三步:Action.java
// 注入UsersVali對象
@Autowired
@Qualifier("UsersVali")
private UsersVali usersVali;


@RequestMapping("re")
public String login(@ModelAttribute Users users, Model model, Errors errors) {
// TODO Auto-generated method stub
System.out.println(users.toString());
// 調用驗證方法
usersVali.validate(users, errors);
// 如果有錯誤,則跳轉
if (errors.hasErrors()) {
return "index";
}
model.addAttribute("users", users);
return "w";
}


第四步:w.jsp
${requestScope.users.name }
${requestScope.users.pass }








JSR303校驗(註解校驗):Apachebval實現或者hibernate-validator實現
JSR303註解
註解 功能 範例
@NULL 驗證對象是否爲null @Null String n;
@NotNull 驗證對象是否不爲null,無法檢查長度爲0的字符串,用於檢驗基本數據類型 @NotNull String n;
@AssertTrue 驗證Boolean對象是否爲false @AssertTrue boolean n;
@AssertFalse 驗證Boolean對象是否爲true @AssertFalse boolean n;
@Max(value) 驗證Number和String對象是否小於等於指定的值 @Max(18) Int n;
@Min(value) 驗證Number和String對象是否大於等於指定的值 @Min(60) Int n;
@DecimalMax(value) 必須不大於約束中的指定的最大值 @DecimalMax(1.1) BigDecimal n;
@DecimalMin(value)  必須不小於約束中的指定的最小值 @DecimalMin(0.5) BigDecimal n;
@Digits(integer,fraction) 驗證字符串是否符合指定格式的數字interger指定整數精度、fraction指定小數精度 @Digits(interger=5,fraction2) BigDecimal n;
@Size(min,max) 驗證Array、Collection、Map、String對象是否在給定的範圍之內 @Size(min=5,max=6) Int n;
@Past 驗證Date和Calendar對象是否在當前時間之前 @Past Date n;
@Future 驗證Date和Calendar對象是否在當前時間之後 @Future Date n;
@Pattern 驗證String對象是否符合正則表達式的規則 @Pattern(regexp="[1][3,8][3,6,9][0-9]{8}") String n;




hibernate-validator拓展註解
註解 功能 範例
@NotBlank 檢查約束的字符串是不是Null,被trim的長度是否大於0 @NotBlank String n;
@URL 檢驗是否是合法的Url @URL String n;
@Email 檢驗是否是合法的郵件地址 @Email String n;
@CreditCardNumber 檢驗是否合法的信用卡號碼 @CreditCardNumber String n;
@Length(min,max) 檢驗字符串長度是否在範圍內 @Length(min=6,max=8) String n;
@NotEmpty 檢驗元素是否爲NULL或者EMPTY,用於Array、Collection、Map、String @NotEmpty String n;
@Range(min,max,message) 檢驗屬性值必須在合適的範圍內 @Range(min=18,max=60,message="年齡必須在18-60歲之間") int n;


FieldError對象實現了MessageSourceResolvable,而此接口有三種方法:
Object[] getArguments()返回一組參數消息
String[] getCodes()返回一組消息代碼,每個代碼對應一個屬性資源,可以使用getArguments()返回的參數對資源參數進行替換
String getDefaultMessage()默認的消息,如果沒有裝配國際化資源,那麼顯示的所有錯誤信息都是默認的


例子(還是有一些要注意的地方):
Users.java
@Length(message = "長度有問題", max = 6, min = 4)
private String name;
@Email(message = "請輸入合法的郵箱地址")
private String pass;


index.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<jsp:useBean id="users" class="cn.anlemusic.Users" scope="request" />
<form:form modelAttribute="users" method="post" action="re">
<form:input path="name" />
<form:errors path="name" cssStyle="color:red" />
<br />
<form:input path="pass" />
<form:errors path="pass" cssStyle="color:red" />
<br />
<input type="submit" value="提交" />
</form:form>


action.java
@RequestMapping("re")
// 使用@Valid註解標記,標記之後需要跟着Errors,這樣就不會執行視圖,發生HTTP Status 400 -錯誤
public String loginsString(@Valid @ModelAttribute Users users,
Errors errors, Model model) {
// TODO Auto-generated method stub
System.out.println(users.toString());
// 如果有錯誤,則跳轉
System.out.println(errors.hasErrors());
if (errors.hasErrors()) {
return "index";
}
model.addAttribute("users", users); //w.jsp顯示數據,這裏省略
return "w";
}




錯誤信息國際化(優先級最高,其次自定義message,最後默認的message):
Email.cn.anlemusic.Users.pass:根據類名,屬性名產生的錯誤代碼
Email.pass = 根據屬性名產生的錯誤信息
Email.java.lang.String = 根據屬性類型產生的錯誤代碼
Email = 根據驗證註解名產生的錯誤代碼


裝配只需要兩步:
加入xml
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 國際化資源文件名稱 -->
<property name="basenames" value="message" />
</bean>


設置message_en_US.properties和message_zh_CN.properties文件
例如:
Length.cn.anlemusic.Users.name:\u6839\u636E\u7C7B\u540D,\u5C5E\u6027\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801
Length.name = \u6839\u636E\u5C5E\u6027\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4FE1\u606F
Length.java.lang.String = \u6839\u636E\u5C5E\u6027\u7C7B\u578B\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801
Length =\u6839\u636E\u9A8C\u8BC1\u6CE8\u89E3\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801
Email.cn.anlemusic.Users.pass:\u6839\u636E\u7C7B\u540D,\u5C5E\u6027\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801
Email.pass = \u6839\u636E\u5C5E\u6027\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4FE1\u606F
Email.java.lang.String = \u6839\u636E\u5C5E\u6027\u7C7B\u578B\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801
Email =\u6839\u636E\u9A8C\u8BC1\u6CE8\u89E3\u540D\u4EA7\u751F\u7684\u9519\u8BEF\u4EE3\u7801






Spring MVC文件上傳:加入commons-fileupload-1.3.2.jar、commons-io-2.2.jar包
第一步html
<form action="re" enctype="multipart/form-data" method="post">
<input type="text" name="description"><br />
<input type="file" name="file"><br />
<input type="submit" value="上傳">
</form>


第二步xml
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上傳文件大小上限,單位爲字節(10MB) -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
<!-- 請求的編碼格式,必須和jsp的pageEncoding屬性一致,以便正確讀取表單的內容 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>


第三步java
@RequestMapping("re")
//上傳文件會自動綁定到MultipartFile上去
public String login(HttpServletRequest request,
@RequestParam("description") String description,
@RequestParam("file") MultipartFile file)
throws IllegalStateException, IOException {
// TODO Auto-generated method stub
System.out.println(description);// 描述
if (!file.isEmpty()) {
// 上傳文件路徑
String path = request.getServletContext().getRealPath("/img/");
// 上傳文件名
String filename = file.getOriginalFilename();// 獲取上傳文件的原名
File filepathFile = new File(path, filename);// 根據parent路徑名字符串和child路徑名字符串創建一個新File實例
// 用實例來判斷路徑是否存在,如果不存在就創建一個
if (!filepathFile.getParentFile().exists()) {
filepathFile.getParentFile().mkdirs();
}
// 將上傳文件保存到一個目標文件當中
file.transferTo(new File(path + File.separator + filename));
// 成功返回的視圖
return "index";
}// 錯誤返回的視圖
return "w";
}


MultipartFile對象方法;
  public abstract String getName();
  //獲取表單中文件的名稱
  public abstract String getOriginalFilename();
  //獲取文件上傳的原名
  public abstract String getContentType();
  //獲取文件的類型
  public abstract boolean isEmpty();
  //是否有上傳的文件
  public abstract long getSize();
  //獲取文件的大小
  public abstract byte[] getBytes()
    throws IOException;
  //獲取文件的數據
  public abstract InputStream getInputStream()
    throws IOException;
  //獲取文件流
  public abstract void transferTo(File paramFile)
    throws IOException, IllegalStateException;
  //將上傳文件保存到目標文件中




Spring MVC文件的下載(常規文件需要利用HttpHeaders、HttpStatus。其他文件直接a href即可)
第一步:Action.java
@RequestMapping("download")
public ResponseEntity<byte[]> xz(HttpServletRequest request,
@RequestParam("filename") String filename, Model model)
throws IOException {
// TODO Auto-generated method stub
// 下載顯示的文件名稱,解決中文亂碼,默認get訪問的編碼爲iso-8859-1,將其變成utf-8
String filenamenew = new String(filename.getBytes("iso-8859-1"),
"UTF-8");
System.out.println(filenamenew);
// 下載文件的路徑
String path = request.getServletContext().getRealPath("/img/");
File file = new File(path + File.separator + filenamenew);// File.separator爲'\'
HttpHeaders headers = new HttpHeaders();
// 通知瀏覽器以attachment(下載方式)打開文件,這裏又到了瀏覽器,需要使用Apache指定的編碼iso-8859-1
headers.setContentDispositionFormData("attachment", filename);
// application/octet-stream:二進制流數據(最常見的文件下載)
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 201 HttpStatus.CREATED
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}


第二步:<a href="download?filename=mb.txt">開始下載</a>
通過get方法請求中文的時候,有三種方法讓其中文正常傳輸到後臺:
方法一、Apache配置文件中設置URIEncoding="utf-8" //默認iso-8859-1
方法二、如上java文件,String filenamenew = new String(filename.getBytes("iso-8859-1"),"UTF-8");//轉碼
方法三、JS中使用encodeURI(param)方法轉成"%???%?",瀏覽器再自動URI編碼(iso-8859-1),服務器得到數據,再使用URIDecoder.decode(name,"utf-8");進行編碼






攔截器:通過實現HandlerInterceptor接口來完成,或者繼承抽象類HandlerInterceptorAdapter對用戶的請求進行攔截處理
org.springframework.web.servlet.HandlerInterceptor;三種方法


public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2) throws Exception
該方法在請求處理之前調用,當返回的是false時,表示請求結束
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception(多個Interceptor時,調用方向與preHandle相反.先聲明的攔截器,先執行(假設第三)preHandle方法,但後執行(倒數第三執行)postHandle方法)
該方法在preHandle爲true時執行,調用在controller之後,在ModelAndView之前調用(可改變視圖的轉述方向)
public void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception
該方法在視圖渲染之後使用,主要是清理資源


例子:
第一步,編寫攔截器
public class Inter implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("我清理資源的");
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("我可以改變視圖" + arg3.getViewName());
arg3.setViewName("w");
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("我通過了他們");
return true;
}
}


第二步,配置xml
<!-- 攔截器定義 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 攔截的請求 -->
<mvc:mapping path="/inter" />
<!-- 攔截器的位置 -->
<bean class="cn.anlemsuic.Inter" />
</mvc:interceptor>
</mvc:interceptors>


第三步,java
@RequestMapping("/inter")
private String inter(@Valid @ModelAttribute Users users, Errors errors,
Model model) {
// TODO Auto-generated method stub
model.addAttribute("users", users);
return "index";
}


最後,兩個jsp
index.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<jsp:useBean id="users" class="cn.anlemusic.Users" scope="request" />
<form:form modelAttribute="users" method="post" action="inter">
<form:input path="name" />
<form:errors path="name" cssStyle="color:red" />
<br />
<form:input path="pass" />
<form:errors path="pass" cssStyle="color:red" />
<br />
<input type="submit" value="提交" />
</form:form>


w.jsp
${requestScope.users.name }=a1234
${requestScope.users.pass }=@
我通過了他們
我可以改變視圖index
我清理資源的 控制檯








最後送個一般配置
<?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" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd   
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd   
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd   
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">


<context:component-scan base-package="cn.anlemusic" />


<mvc:default-servlet-handler />


<mvc:annotation-driven />


<bean name="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>




END!






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章