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!






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值