- 浏览: 56655 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
chiqinghaichi:
楼主好!菜鸟一枚,试了下你的程序,当访问 http://loc ...
SpringMVC -
随意而生:
复习复习 不错
SpringMVC -
ccii:
cylboke 写道他的意思是“orcle”写错了吧?我猜的! ...
Oracle基本操作 -
happy200318:
给个赞,不错
SpringMVC -
cylboke:
他的意思是“orcle”写错了吧?我猜的!!!
Oracle基本操作
一、Spring概述
1. 简介
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring框架在框架设计、扩展性、灵活性等方面全面超越了Struts、WebWork等MVC框架,从原来的追赶者一跃为MVC的领跑者。Spring框架围绕DispacherServlet这个核心展开,它负责截获请求并将其分派给相应的处理器处理。
2. Spring MVC和Struts2的比较
(1)Spring MVC的入口是servlet,而Struts2是filter,这里要指出filter和servlet是不同的。
(2)Spring MVC会稍微比Struts2快。Spring MVC是基于方法的设计,方法级别的拦截。而struts2设计是基于类,采用类级别的拦截。
(3)参数传递方面,Struts2用属性的get方法接受参数,这就说明参数是让多个方法共享的。
(4)配置文件方面很明显Struts2要复杂的多。
二、Spring MVC示例
1. 在web.xml中配置DispatcherServlet
DispatcherServlet是Spring MVC的灵魂和心脏,它负责接收HTTP请求并协调Spring MVC的各个组件完成请求处理的工作。和任何Servlet一样,用户必须在web.xml中配置好DispatcherServlet。如下:
2. 编写处理请求的控制器
Spring MVC通过一个@Controller注解即可将一个POJO转化为处理器请求的控制器,通过@RequestMapping为控制器指定处理哪些URL的请求。如下:
UserController.java:
User.java:
3. 编写视图对象
WEB-INF/customer/login.jsp:
WEB-INF/customer/menu.jsp:
4. 配置Spring MVC的配置文件
spring-config.xml:
spring-mvc.xml:
5. SpringMVC处理user.html过程描述
(1)DispatcherServlet接收到客户端的user.html的请求
(2)DispatcherServlet使用DefaultAnnotationHandlerMapping查找负责处理该请求的处理器为user.html
(3)DispatcherServlet将请求分发给名为user.html的UserController处理器
(4)处理器完成业务处理后,返回ModelAndView对象,其中View的逻辑名为menu,模型包含一个键为user的User对象
(5)DispatcherServlet调用InternalResourceViewResolver组件对ModelAndView中的逻辑视图名进行解析,得到真实的/WEB-INF/customer/menu.jsp视图对象
(6)DispatcherServlet使用/WEB-INF/customer/menu.jsp对模型中的user模型对象进行渲染
(7)返回响应页面给客户端
三、注解驱动的控制器
1. 使用@RequestMapping映射请求
在POJO类定义处标注@Controller,再通过<context:component-scan base-package="com.jiang.web.controller"/>扫描相应的类包,即可使POJO成为一个能处理HTTP请求的控制器。然后在控制器的类定义及方法定义处都可标注@RequestMapping,类定义处提供初步请求映射信息,方法处提供进一步的细分映射信息。
将请求映射到控制器处理方法的工作包含一系列的映射规则,这些规则是根据请求中的各种信息制定的,具体包括请求URL、请求参数、请求方法、请求头这4个方面的信息项。
(1)通过请求URL进行映射
@RequestMapping("/user"),它不但支持标准的URL,还支持Ant风格(即?、*和**的字符)的和带{xxx}占位符的URL。如下:
/user/*/createUser:匹配/user/aaa/createUser、/user/bbb/createUser等URL
/user/**/createUser:匹配/user/createUser、/user/aaa/bbb/createUser等URL
/user/createUser??:匹配/user/createUseraaa、/user/createUserbbb等URL
/user/{userId}:匹配/user/123、/user/234等URL
/user/**/{userId}:匹配/user/aaa/bbb/123等URL
/company/{companyId}/user/{userId}/detail:匹配/company/123/user/456/detail等URL
URL中的{xxx}可以通过@PathVariable将URL中的占位符参数绑定到控制器处理方法的入参中,类和方法处的占位符都可以绑定到处理方法的入参中,如下:
注意,要使用上面的入参成功绑定URL中的占位符,必须在编译时开启debug开关。
(2)通过请求参数、请求方法或请求头进行映射让请求映射更加精确化
@RequestMapping的value、method、params及headers分别表示请求URL、请求方法、请求参数及报文头的映射条件,它们之间是与的关系,联合使用多个条件项可让请求映射更加精确化。
2. 请求处理方法的签名
处理方法的签名包括对方法及方法入参标注相应的注解、入参、返回值等。对于这些签名,SpringMVC会优雅的将Http请求的信息绑定到相应的方法入参中,并根据方法返回值类型作出相应的后续处理。
(1)使用@RequestParam绑定请求参数值
@RequestMapping(value="/handle")
public String handle(
@RequestParam(value="userName",required=false)String userName,
@RequestParam(value="age")int age) {
...
}
上面的实例将“UserName”和“age”请求参数分别绑定到handle()方法的userName和age中,并自动完成类型转换。required参数表示请求中是否必须包含对应的参数,默认为true,上面的实例如果不存在age请求参数,将抛出异常。还有一个defaultValue参数设置默认参数名,不推荐使用该参数。
(2)使用@CookieValue绑定请求中的Cookie值
@RequestMapping(value="/handle")
public String handle(
@CookieValue(value="sessionId",required=false)String sessionId,
@RequestParam(value="age")int age) {
...
}
value指定Cookie的名称,required为false表示请求中没有相应的Cookie时也不会报错。
(3)使用@RequestHeader绑定请求报文头的属性值
@RequestMapping(value="/handle")
public String handle(
@RequestHeader("Accept-Encoding")String encoding,
@RequestHeader("Keep-Alive")long keepAlive) {
...
}
参数和@RequestParam相同。
(4)使用命令/表单对象绑定请求参数值
@RequestMapping(value="/handle")
public String handle(User user) {
...
}
所谓命令/表单对象并不需要实现任何接口,仅是一个拥有若干属性的POJO,Spring MVC会按请求参数名和命令/表单对象属性名匹配的方式,自动对该对象填充属性值。支持级联的属性名,如address.addressName。
(5)使用Servlet API对象作为入参
在Spring MVC中,控制器类可以不依赖任何Servlet API对象,但是Spring MVC并不阻止我们使用Servlet API的类作为处理方法的入参。
@RequestMapping(value="/handle")
public void handle(HttpServletRequest request,HttpServletResponse response) {
...//同时使用HttpServletRequest和HttpServletResponse作为入参
//使用HttpServletResponse返回响应时,将处理方法返回值设成void即可
String userName = WebUtils.findParameterValue(request,"userName");
response.addCookie(new Cookie("userName", userName));
}
@RequestMapping(value="/handle")
public String handle(HttpServletRequest request) {
...//只使用HttpServletRequest作为入参,可返回String或ModelAndView
}
@RequestMapping(value="/handle")
public String handle(HttpSession session) {
...//使用HttpSession作为入参,可返回String或ModelAndView
}
@RequestMapping(value="/handle")
public String handle(HttpServletRequest request, @RequestParam(value="userName",required=false)String userName) {
...//同时使用HttpServletRequest和基本类型作为入参,它们之间的位置不固定
}
Spring MVC在org.springframework.web.context.request包中定义了若干个可代理Servlet原生API类的接口,它们也可以作为处理类的入参,通过这些类可访问请求对象的任何信息。
@RequestMapping(value="/handle")
public String handle(WebRequest request) {
...//使用Spring MVC的WebRequest作为入参
}
(6)使用IO对象作为入参
Servlet的ServletRequest拥有getInputStream()和getReader()方法,可以通过它们读取请求的信息。相应Servlet的ServletResponse拥有getOutputStream()和getWriter()方法,可以通过它们输出响应信息。
Spring MVC允许控制器的处理方法使用java.io.InputStream/java.io.Reader及java.io.OutputStream/java.io.Writer作为方法的入参,Spring MVC将获取ServletRequest的InputStream/Reader或ServletResponse的OutputStream/Writer,然后传递给控制器的处理方法。如下:
@RequestMapping(value="/handle")
public String handle(OutputStream os) throws IOException {
Resource res = new ClassPathResource("/image.jpg");
FileCopyUtils.copy(res.getInputStream(), os);//将图片写到输出流
}
(7)其它类型的参数
控制器处理方法的入参除支持以上类型的参数以外,还支持java.util.Locale、java.security.Principal,可以通过Servlet的HttpServletRequest的getLocal()及getUserPrincipal()得到相应的值。如果处理方法的入参类型为Locale或Principal,Spring MVC自动从请求对象中获取相应的对象并传递给处理方法的入参。
3. 使用HttpMessageConverter<T>
HttpMessageConverter<T>是Spring3.0新添加的一个重要接口,它负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息。
DispatcherServlet默认已经安装了AnnotationMethodHandlerAdapter作为HandlerAdapter的组件实现类,HttpMessageConConverter即由AnnotationMethodHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。
Spring为HttpMessageConverter<T>提供了众多的实现类,它们组成了一个功能强大、用途广泛的HttpMessageConverter<T>家族,如下:
StringHttpMessageConverter 将请求信息转换为字符串,默认装配;
FormHttpMessageConverter 将表单数据读取到MultiValueMap中;
XmlAwareFormHttpMessageConverter 扩展于FormHttpMessageConverter,如果部分表单属性是XML数据,可用该转换器进行读取,默认装配;
ResourceHttpMessageConverter 读写org.springframework.core.io.Resource类型;
BufferedImageHttpMessageConverter 读写BufferedImage对象;
ByteArrayHttpMessageconverter 读写二进制数据,默认装配;
SourceHttpMessageConverter 读写javax.xml.transform.Source类型的数据,默认装配;
MarshallingHttpMessageConverter 通过Spring的org.springframework.oxm.Marshaller(将Java对象转换成XML)和Unmarshaller(将XML解析为Java对象)读写XML消息;
Jaxb2RootElementHttpMessageConverter 通过JAXB2读写XML消息,将请求消息转换到标注XmlRootElement和XmlType注解类型中;
MappingJacksonHttpMessageConverter 通过利用Jackson开源类包的ObjectMapper读写JSON数据;
RssChannerHttpMessageConverter 能够读写RSS种子消息;
AtomFeedHttpMessageConverter 和RssChannerHttpMessageConverter能够读写RSS种子消息;
上面标明默认装配的实现类已装配到AnnotationMethodHandlerAdapter,如果需要装配其他类型,可以Spring的的Web容器上下文中自行定义一个AnnotationMethodHandlerAdapter,如下:
<!-- 定义一个AnnotationMethodHandlerAdapter,显式定义后将覆盖默认的AnnotationMethodHandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:messageConverters-ref="messageConverters"/>
<util:list id="messageConverters">
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
.....
</util:list>
使用HtpMessageConverter<T>,将请求信息转化并绑定到处理方法的入参中。
(1)使用@RequestBody / @ResponseBody对处理方法进行标注(p540)
(2)使用HttpEntity<T> / ResponseEntity<T>作为处理方法的入参或返回值(p542)
示例:处理JSON
(1)首先为AnnotationMethodHandlerAdapter装配上可处理JSON的HttpMessageConverter:
(2)在控制器编写相应的方法:
注意,处理JSON必须引入下面四个包:
4. 处理模型数据
对于MVC框架来说模型数据是最重要的,因为控制层(C)是为了产生模型数据(M),而视图(V)则是为了渲染模型数据。
(1)ModelAndView
控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含模型数据信息。可以简单地将模型数据看成一个Map<Stirng, Object>对象。ModelAndView操作如下:
ModelAndView addObject(String attributeName, Object attribute Value); //添加模型数据
ModelAndView addAllObjects(Map<String, ?> modelMap); //添加模型数据
void setView(View view); //指定一个具体的视图对象
void setViewName(String viewName); //指定一个逻辑视图名
(2)ModelAttribute
如果希望将方法入参对象添加到模型中,只需在相应入参前使用@ModelAttribute注解或在方法定义处使用@ModelAttribute注解即可。
@RequestMapping(value = "/handle61")
// SpringMVC将请求消息绑定到User对象中,然后再以“user”为键将User对象放到模型中。
public String handle61(@ModelAttribute("user") User user) {
user.setUserId("1000");
return "/user/createSuccess";
}
@ModelAttribute("user")
public User getUser() {
User user = new User();
user.setUserId("1001");
user.setUserName("<>");
return user;
}
当访问此控制器类中的任何一个请求处理方法前,都会事先执行标注了@ModelAttribute的getUser()方法,并将其返回值以user为键添加到模型中。
(3)Map及Model
入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map时处理方法返回时,Map中的数据会自动添加到模型中。
@RequestMapping(value = "/handle63")
public String handle63(ModelMap modelMap) {
User user = (User) modelMap.get("user");
user.setUserName("tom");
modelMap.addAttribute("testAttr", "value1");
return "/user/showUser";
}
(4)SessionAttributes
将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性
// 将handle71处的模型属性自动保存到HttpSession中
@SessionAttributes("user")
@RequestMapping(value = "/handle71")
public String handle71(@ModelAttribute("user") User user) {
user.setUserName("John");
return "redirect:handle72.html"; //向handle72发起一个新的请求
}
@RequestMapping(value = "/handle72")
public String handle72(ModelMap modelMap, SessionStatus sessionStatus) {
User user = (User) modelMap.get("user"); //读取模型中的数据
if (user != null) {
user.setUserName("Jetty");
sessionStatus.setComplete(); //让SpringMVC清除本处理器对应的会话属性
}
return "/user/showUser";
}
四、处理方法的数据绑定
在请求消息到达真正调用处理方法的这一段时间内,Spring MVC还完成了很多工作,包括数据转换、数据格式化及数据校验等。
1. 数据绑定流程
Spring MVC通过反射机制对目标处理方法的签名进行分析,将请求消息绑定到处理方法的入参中。
(1)Spring MVC主框架将ServletRequest对象及处理方法的入参对象实例传递给DataBinder
(2)DataBinder调用装配在Spring Web上下文中的ConversionService组件进行数据类型转换、数据格式化的工作,将ServletRequest中的消息填充到入参对象中。
(3)DataBinder对象继续调用Validator组件对已经绑定了请求消息数据的入参对象进行数据合法性校验。最终生成BindingResult对象,将它们赋给处理方法的入参。
2. 数据转换
Spring3.0在核心模型中添加了一个通用的类型转换模块,位于org.springframework.core.convert包中,同时支持Java标准的PropertyEditer。
(1)ConversionService是Spring类型转换体系的核心接口。
(2)Spring支持的转换器
Converter<S,T>
GenericConverter
ConverterFactory
(3)在Spring MVC中使用ConversionService自定义转换器
3. 数据格式化
Spring3.0引入了一个新的格式化框架,位于org.springframework.format包中,
(1)Formatter<T>是格式化框架最重要的接口
(2)注解驱动格式化的重要接口
(3)启用注解驱动格式化功能
(4)注解驱动格式化实例
4. 数据校验
(1)JSR303是Java为Bean数据合法性校验所提供的标准框架,它已经包含在Java EE6.0中。通过在Bean属性上标注类似于@NotNull等标准的注解指定校验规则
(2)Spring校验框架,它在org.springframework.validation包下,通过注解驱动的方式进行数据校验。
(3)Spring数据校验(获取校验结果、如何在页面中显示错误、通过国际化资源显示错误信息)
(4)自定义校验规则(为请求处理类装配一个自定义的Validator)
五、视图和视图解析器
请求处理方法执行完成后,最终返回一个ModelAndView对象,对于那些String、View或ModelMap等类型的处理方法,SpringMVC也会在内部将它们装配成一个ModelAndView对象,它包含了实图逻辑名和模型对象的信息。
1. 视图,是渲染模型数据,将模型里的数据以某种形式呈现给客户(JSP、Excel、PDF等)。
2. 视图解析器,将逻辑视图名解析为一个具体的视图对象。
3. JSP和JSTL
(1)使用InternalResourceViewResolver作为视图解析器(JSP)
(2)使用Spring表单标签,它可以很容易地将模型数据中的表单/命令对象绑定到HTML表单元素中
4. 模板视图
FreeMarker和Velocity是除了JSP之外被使用最多的页面模板技术。页面模板编写好页面结构,模板页面中使用一些特殊的变量标识符绑定Java对象的动态数据。
5. Excel
如果希望使用Excel展示用户列表,仅需要扩展Spring的AbstractExcelView或AbstractJExcelView即可。
6. PDF
PDF视图和Excel类似,也是使用一个Bean作为视图对象
7. XML
将模型中的数据以XML的形式输出,对应视图对象为MarshallingView
8. JSON
SpringMVC的MappingJacksonJsonView借助Jackson框架的ObjectMapper将模型数据转换为JSON格式输出。
默认情况下,MappingJacksonJsonView会将模型中的所有数据都输出为JSON,这显然是不适合的,可以通过renderedAttravutes指定模型中哪些属性需要输出。
9. XmlViewResolver
同BeanNameViewResolver,但它可以将视图Bean定义在一个独立的XML文件中
10. ResourceBundleViewResolver
它通过一个国际化资源文件定义视图对象,为不同地区的用户提供不同类型的视图
11. 混合使用多种视图技术
(1)ContentNegotiatingViewResolver
(2)使用同一URL获取不同形式的返回内容
六、本地化解析
1. 本地化概述
浏览器中设置的本地化类型会包含在HTML请求报文头中发送给Web服务器,确切地说是通过报文头的Accept-Language参数将“语言首选项”对话框中选择的语言发送到服务器,成为服务器判别客户端本地化类型的依据。可以通过IE菜单:工具--Internet选项--语言--选择本地化类型设置。
2. 使用CookieLocaleResolver,DispactcherServlet会自动识别本地化解析器并装配它。
3. 使用SessionLocaleResolver,查找Session中属性名为SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME的属性,并将其转换为Locale对象。
4. 使用LocaleChangeInterceptor,通过一个请求参数控制网站的本地化。
七、文件上传
SpringMVC为文件上传提供了即插即用的MultipartResolver,采用了Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。
1. 配置MultipartResolver
2. 编写控制器
SpringMVC会将上传文件绑定到MultipartFile对象中。使用如下:
byte[] getBytes():获取文件数据
String getContentType():获取文件MIME类型
InputStream getInputStream():获取文件流
String getName():获取表单中文件组件的名字
String getOriginalFilename():获取上传文件的原名
long getSize():获取文件的字节大小,单位byte
boolean isEmpty():是否有上传的文件
void transferTo(File dest):将上传文件保存到一个目标文件中
3. 表单
负责上传文件的表单编码必须是“multipart/form-data”类型。
八、其它
1. 静态资源处理
(1)将DispatcherServlet请求映射配置为"/",使其捕获Web容器所有的请求。
(2)Spring MVC配置
方法一:
<!-- 如果是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,-->
<mvc:default-servlet-handler/>
方法二:
<!-- 由Spring MVC框架自己处理静态资源,将Web根路径“/”及类路径下/META-INF/publicResources/的目录映射为/resources路径。假设Web根路径下拥有js/ext.js,则在jsp则可通过 "/resources/js/ext.js访问" -->
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/publicResources/"/>
<mvc:resources/>允许静态资源放在任何地方,如WEB-INF目录下、类路径下等。在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303响应状态码,指示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端。如果在映射的物理路径下存在多个同名静态资源,找到第1个就返回,查找的顺序和物理路径在location中的配置顺序一致。
<mvc:resources mapping="/resources/**"
location="/" cache-period="31536000"/>
通过cache-period属性设置静态资源在客户端浏览器中的缓存有效时间,一般设置为一年。
有时由于浏览器本身缓存管理机制的问题,当我们发布新的版本时客户端并不会从服务器端下载新的静态资源。一个好的解决办法是:网页中引用静态资源的路径添加应用的发布版本号,这样由于版本号的变更造成网页中静态资源路径发生更改,从而使这些静态资源成为“新的资源”。下面将版本号包含到<mvc:resources/>中。
创建版本号获取类:
在<mvc:resources/>中配置:
在jsp中引用路径:
2. 异常处理
SpringMVC通过HandlerExceptionResolver处理程序的异常,包括处理器映射、数据绑定以及处理器执行时发生异常。
1. 简介
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring框架在框架设计、扩展性、灵活性等方面全面超越了Struts、WebWork等MVC框架,从原来的追赶者一跃为MVC的领跑者。Spring框架围绕DispacherServlet这个核心展开,它负责截获请求并将其分派给相应的处理器处理。
2. Spring MVC和Struts2的比较
(1)Spring MVC的入口是servlet,而Struts2是filter,这里要指出filter和servlet是不同的。
(2)Spring MVC会稍微比Struts2快。Spring MVC是基于方法的设计,方法级别的拦截。而struts2设计是基于类,采用类级别的拦截。
(3)参数传递方面,Struts2用属性的get方法接受参数,这就说明参数是让多个方法共享的。
(4)配置文件方面很明显Struts2要复杂的多。
二、Spring MVC示例
1. 在web.xml中配置DispatcherServlet
DispatcherServlet是Spring MVC的灵魂和心脏,它负责接收HTTP请求并协调Spring MVC的各个组件完成请求处理的工作。和任何Servlet一样,用户必须在web.xml中配置好DispatcherServlet。如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <!-- 指定业务层Spring容器的配置文件,多个用逗号隔开 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring-config.xml</param-value> </context-param> <!-- 通过contextConfigLocation指定的配置文件启动业务层的Spring容器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置名为spring的DispatcherServlet,默认自动加载/WEB-INF/spring-servlet.xml的配置文件,启动Web层的Spring容器。 一个web.xml可以配置多个DispatcherServlet --> <!-- 这里,WEB层Spring容器将作为业务层Spring容器的子容器,即WEB层容器可以引用业务层容器的Bean,而业务层却不能访问WEB层容器的Bean --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定使用类路径下的WEB层spring容器配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 指定DispatcherServlet处理所有URL以.html为后缀的HTTP请求 --> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
2. 编写处理请求的控制器
Spring MVC通过一个@Controller注解即可将一个POJO转化为处理器请求的控制器,通过@RequestMapping为控制器指定处理哪些URL的请求。如下:
UserController.java:
package com.jiang.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import com.jiang.web.entity.User; //标注UserController成为处理请求的控制器 @Controller //处理来自/user URI的请求,限定请求路径为/user下,此路径可以不加 @RequestMapping("/user") public class UserController { //直接处理“/user.html”的请求,请求的方法必须为POST @RequestMapping(method = RequestMethod.POST) //将表单值映射到User对象中 public ModelAndView cteateUser(User user) { //注意此处的ModelAndView是在org.springframework.web.servlet包下,不要import错了 ModelAndView mav = new ModelAndView(); mav.setViewName("menu"); mav.addObject("user", user); return mav; } //将处理http://127.0.0.1:8080/WalletManager/user/login.html的请求 @RequestMapping("/login") public String index() { //返回一个逻辑视图名,根据配置文件映射为/WEB/INF/customer/login.jsp return "login"; } }
User.java:
package com.jiang.web.entity; public class User { private String userName; private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
3. 编写视图对象
WEB-INF/customer/login.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>登陆</title> </head> <body> <!-- 将表单提交到/user.html控制器中, --> <form method="post" action="/user.html"> <table> <tr> <td>用户名:</td> <td><input type="text" name="userName" /></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password" /></td> </tr> <tr> <td><input type="submit" value="登陆" /></td> </tr> </table> </form> </body> </html>
WEB-INF/customer/menu.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>新会员中心</title> </head> <body> Wellcome! ${user.userName} </body> </html>
4. 配置Spring MVC的配置文件
spring-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" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> </beans>
spring-mvc.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 让Spring扫描包下标注注解的类生效 --> <context:component-scan base-package="com.jiang.web.controller"/> <!-- 定义一个视图名称解析器,将名称解析为/WEB-INF/customer/名称.jsp --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/customer/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
5. SpringMVC处理user.html过程描述
(1)DispatcherServlet接收到客户端的user.html的请求
(2)DispatcherServlet使用DefaultAnnotationHandlerMapping查找负责处理该请求的处理器为user.html
(3)DispatcherServlet将请求分发给名为user.html的UserController处理器
(4)处理器完成业务处理后,返回ModelAndView对象,其中View的逻辑名为menu,模型包含一个键为user的User对象
(5)DispatcherServlet调用InternalResourceViewResolver组件对ModelAndView中的逻辑视图名进行解析,得到真实的/WEB-INF/customer/menu.jsp视图对象
(6)DispatcherServlet使用/WEB-INF/customer/menu.jsp对模型中的user模型对象进行渲染
(7)返回响应页面给客户端
三、注解驱动的控制器
1. 使用@RequestMapping映射请求
在POJO类定义处标注@Controller,再通过<context:component-scan base-package="com.jiang.web.controller"/>扫描相应的类包,即可使POJO成为一个能处理HTTP请求的控制器。然后在控制器的类定义及方法定义处都可标注@RequestMapping,类定义处提供初步请求映射信息,方法处提供进一步的细分映射信息。
将请求映射到控制器处理方法的工作包含一系列的映射规则,这些规则是根据请求中的各种信息制定的,具体包括请求URL、请求参数、请求方法、请求头这4个方面的信息项。
(1)通过请求URL进行映射
@RequestMapping("/user"),它不但支持标准的URL,还支持Ant风格(即?、*和**的字符)的和带{xxx}占位符的URL。如下:
/user/*/createUser:匹配/user/aaa/createUser、/user/bbb/createUser等URL
/user/**/createUser:匹配/user/createUser、/user/aaa/bbb/createUser等URL
/user/createUser??:匹配/user/createUseraaa、/user/createUserbbb等URL
/user/{userId}:匹配/user/123、/user/234等URL
/user/**/{userId}:匹配/user/aaa/bbb/123等URL
/company/{companyId}/user/{userId}/detail:匹配/company/123/user/456/detail等URL
URL中的{xxx}可以通过@PathVariable将URL中的占位符参数绑定到控制器处理方法的入参中,类和方法处的占位符都可以绑定到处理方法的入参中,如下:
@RequestMapping("owners/{ownerId}") public class UserController{ @RequestMapping("users/{userId}") public ModelAndView showDetail(@PathVariable("ownerId")String ownerId,@PathVariable("userId")String userId){ .. } }
注意,要使用上面的入参成功绑定URL中的占位符,必须在编译时开启debug开关。
(2)通过请求参数、请求方法或请求头进行映射让请求映射更加精确化
@RequestMapping的value、method、params及headers分别表示请求URL、请求方法、请求参数及报文头的映射条件,它们之间是与的关系,联合使用多个条件项可让请求映射更加精确化。
@Controller @RequestMapping("/user") public class UserController { @RequestMapping(value="/delete",method = RequestMethod.POST,params="userId") public String test1(@PathVariable("userId")String userId) { return "user/test1"; } @RequestMapping(value="/show",headers="content-type=text/*") public String test2(@PathVariable("userId")String userId) { return "user/test2"; } }
2. 请求处理方法的签名
处理方法的签名包括对方法及方法入参标注相应的注解、入参、返回值等。对于这些签名,SpringMVC会优雅的将Http请求的信息绑定到相应的方法入参中,并根据方法返回值类型作出相应的后续处理。
(1)使用@RequestParam绑定请求参数值
@RequestMapping(value="/handle")
public String handle(
@RequestParam(value="userName",required=false)String userName,
@RequestParam(value="age")int age) {
...
}
上面的实例将“UserName”和“age”请求参数分别绑定到handle()方法的userName和age中,并自动完成类型转换。required参数表示请求中是否必须包含对应的参数,默认为true,上面的实例如果不存在age请求参数,将抛出异常。还有一个defaultValue参数设置默认参数名,不推荐使用该参数。
(2)使用@CookieValue绑定请求中的Cookie值
@RequestMapping(value="/handle")
public String handle(
@CookieValue(value="sessionId",required=false)String sessionId,
@RequestParam(value="age")int age) {
...
}
value指定Cookie的名称,required为false表示请求中没有相应的Cookie时也不会报错。
(3)使用@RequestHeader绑定请求报文头的属性值
@RequestMapping(value="/handle")
public String handle(
@RequestHeader("Accept-Encoding")String encoding,
@RequestHeader("Keep-Alive")long keepAlive) {
...
}
参数和@RequestParam相同。
(4)使用命令/表单对象绑定请求参数值
@RequestMapping(value="/handle")
public String handle(User user) {
...
}
所谓命令/表单对象并不需要实现任何接口,仅是一个拥有若干属性的POJO,Spring MVC会按请求参数名和命令/表单对象属性名匹配的方式,自动对该对象填充属性值。支持级联的属性名,如address.addressName。
(5)使用Servlet API对象作为入参
在Spring MVC中,控制器类可以不依赖任何Servlet API对象,但是Spring MVC并不阻止我们使用Servlet API的类作为处理方法的入参。
@RequestMapping(value="/handle")
public void handle(HttpServletRequest request,HttpServletResponse response) {
...//同时使用HttpServletRequest和HttpServletResponse作为入参
//使用HttpServletResponse返回响应时,将处理方法返回值设成void即可
String userName = WebUtils.findParameterValue(request,"userName");
response.addCookie(new Cookie("userName", userName));
}
@RequestMapping(value="/handle")
public String handle(HttpServletRequest request) {
...//只使用HttpServletRequest作为入参,可返回String或ModelAndView
}
@RequestMapping(value="/handle")
public String handle(HttpSession session) {
...//使用HttpSession作为入参,可返回String或ModelAndView
}
@RequestMapping(value="/handle")
public String handle(HttpServletRequest request, @RequestParam(value="userName",required=false)String userName) {
...//同时使用HttpServletRequest和基本类型作为入参,它们之间的位置不固定
}
Spring MVC在org.springframework.web.context.request包中定义了若干个可代理Servlet原生API类的接口,它们也可以作为处理类的入参,通过这些类可访问请求对象的任何信息。
@RequestMapping(value="/handle")
public String handle(WebRequest request) {
...//使用Spring MVC的WebRequest作为入参
}
(6)使用IO对象作为入参
Servlet的ServletRequest拥有getInputStream()和getReader()方法,可以通过它们读取请求的信息。相应Servlet的ServletResponse拥有getOutputStream()和getWriter()方法,可以通过它们输出响应信息。
Spring MVC允许控制器的处理方法使用java.io.InputStream/java.io.Reader及java.io.OutputStream/java.io.Writer作为方法的入参,Spring MVC将获取ServletRequest的InputStream/Reader或ServletResponse的OutputStream/Writer,然后传递给控制器的处理方法。如下:
@RequestMapping(value="/handle")
public String handle(OutputStream os) throws IOException {
Resource res = new ClassPathResource("/image.jpg");
FileCopyUtils.copy(res.getInputStream(), os);//将图片写到输出流
}
(7)其它类型的参数
控制器处理方法的入参除支持以上类型的参数以外,还支持java.util.Locale、java.security.Principal,可以通过Servlet的HttpServletRequest的getLocal()及getUserPrincipal()得到相应的值。如果处理方法的入参类型为Locale或Principal,Spring MVC自动从请求对象中获取相应的对象并传递给处理方法的入参。
3. 使用HttpMessageConverter<T>
HttpMessageConverter<T>是Spring3.0新添加的一个重要接口,它负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息。
DispatcherServlet默认已经安装了AnnotationMethodHandlerAdapter作为HandlerAdapter的组件实现类,HttpMessageConConverter即由AnnotationMethodHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。
Spring为HttpMessageConverter<T>提供了众多的实现类,它们组成了一个功能强大、用途广泛的HttpMessageConverter<T>家族,如下:
StringHttpMessageConverter 将请求信息转换为字符串,默认装配;
FormHttpMessageConverter 将表单数据读取到MultiValueMap中;
XmlAwareFormHttpMessageConverter 扩展于FormHttpMessageConverter,如果部分表单属性是XML数据,可用该转换器进行读取,默认装配;
ResourceHttpMessageConverter 读写org.springframework.core.io.Resource类型;
BufferedImageHttpMessageConverter 读写BufferedImage对象;
ByteArrayHttpMessageconverter 读写二进制数据,默认装配;
SourceHttpMessageConverter 读写javax.xml.transform.Source类型的数据,默认装配;
MarshallingHttpMessageConverter 通过Spring的org.springframework.oxm.Marshaller(将Java对象转换成XML)和Unmarshaller(将XML解析为Java对象)读写XML消息;
Jaxb2RootElementHttpMessageConverter 通过JAXB2读写XML消息,将请求消息转换到标注XmlRootElement和XmlType注解类型中;
MappingJacksonHttpMessageConverter 通过利用Jackson开源类包的ObjectMapper读写JSON数据;
RssChannerHttpMessageConverter 能够读写RSS种子消息;
AtomFeedHttpMessageConverter 和RssChannerHttpMessageConverter能够读写RSS种子消息;
上面标明默认装配的实现类已装配到AnnotationMethodHandlerAdapter,如果需要装配其他类型,可以Spring的的Web容器上下文中自行定义一个AnnotationMethodHandlerAdapter,如下:
<!-- 定义一个AnnotationMethodHandlerAdapter,显式定义后将覆盖默认的AnnotationMethodHandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:messageConverters-ref="messageConverters"/>
<util:list id="messageConverters">
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
.....
</util:list>
使用HtpMessageConverter<T>,将请求信息转化并绑定到处理方法的入参中。
(1)使用@RequestBody / @ResponseBody对处理方法进行标注(p540)
(2)使用HttpEntity<T> / ResponseEntity<T>作为处理方法的入参或返回值(p542)
示例:处理JSON
(1)首先为AnnotationMethodHandlerAdapter装配上可处理JSON的HttpMessageConverter:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list > <ref bean="mappingJacksonHttpMessageConverter" /> </list> </property> </bean> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json; charset=UTF-8</value> <value>text/html; charset=UTF-8</value> </list> </property> </bean>
(2)在控制器编写相应的方法:
@RequestMapping("/product") @ResponseBody public List<Product> findProductList() { List<Product> liProduct= new ArrayList<Product>(); for (ProductCodeEnum t : ProductCodeEnum.values()) { Product product = new Product(); product.setId(t.getCode()); product.setText(t.getCnName()); product.setLeaf(true); liProduct.add(product); } return liProduct; }
注意,处理JSON必须引入下面四个包:
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-lgpl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-lgpl</artifactId> <version>1.9.13</version> </dependency>
4. 处理模型数据
对于MVC框架来说模型数据是最重要的,因为控制层(C)是为了产生模型数据(M),而视图(V)则是为了渲染模型数据。
(1)ModelAndView
控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含模型数据信息。可以简单地将模型数据看成一个Map<Stirng, Object>对象。ModelAndView操作如下:
ModelAndView addObject(String attributeName, Object attribute Value); //添加模型数据
ModelAndView addAllObjects(Map<String, ?> modelMap); //添加模型数据
void setView(View view); //指定一个具体的视图对象
void setViewName(String viewName); //指定一个逻辑视图名
(2)ModelAttribute
如果希望将方法入参对象添加到模型中,只需在相应入参前使用@ModelAttribute注解或在方法定义处使用@ModelAttribute注解即可。
@RequestMapping(value = "/handle61")
// SpringMVC将请求消息绑定到User对象中,然后再以“user”为键将User对象放到模型中。
public String handle61(@ModelAttribute("user") User user) {
user.setUserId("1000");
return "/user/createSuccess";
}
@ModelAttribute("user")
public User getUser() {
User user = new User();
user.setUserId("1001");
user.setUserName("<>");
return user;
}
当访问此控制器类中的任何一个请求处理方法前,都会事先执行标注了@ModelAttribute的getUser()方法,并将其返回值以user为键添加到模型中。
(3)Map及Model
入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map时处理方法返回时,Map中的数据会自动添加到模型中。
@RequestMapping(value = "/handle63")
public String handle63(ModelMap modelMap) {
User user = (User) modelMap.get("user");
user.setUserName("tom");
modelMap.addAttribute("testAttr", "value1");
return "/user/showUser";
}
(4)SessionAttributes
将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性
// 将handle71处的模型属性自动保存到HttpSession中
@SessionAttributes("user")
@RequestMapping(value = "/handle71")
public String handle71(@ModelAttribute("user") User user) {
user.setUserName("John");
return "redirect:handle72.html"; //向handle72发起一个新的请求
}
@RequestMapping(value = "/handle72")
public String handle72(ModelMap modelMap, SessionStatus sessionStatus) {
User user = (User) modelMap.get("user"); //读取模型中的数据
if (user != null) {
user.setUserName("Jetty");
sessionStatus.setComplete(); //让SpringMVC清除本处理器对应的会话属性
}
return "/user/showUser";
}
四、处理方法的数据绑定
在请求消息到达真正调用处理方法的这一段时间内,Spring MVC还完成了很多工作,包括数据转换、数据格式化及数据校验等。
1. 数据绑定流程
Spring MVC通过反射机制对目标处理方法的签名进行分析,将请求消息绑定到处理方法的入参中。
(1)Spring MVC主框架将ServletRequest对象及处理方法的入参对象实例传递给DataBinder
(2)DataBinder调用装配在Spring Web上下文中的ConversionService组件进行数据类型转换、数据格式化的工作,将ServletRequest中的消息填充到入参对象中。
(3)DataBinder对象继续调用Validator组件对已经绑定了请求消息数据的入参对象进行数据合法性校验。最终生成BindingResult对象,将它们赋给处理方法的入参。
2. 数据转换
Spring3.0在核心模型中添加了一个通用的类型转换模块,位于org.springframework.core.convert包中,同时支持Java标准的PropertyEditer。
(1)ConversionService是Spring类型转换体系的核心接口。
(2)Spring支持的转换器
Converter<S,T>
GenericConverter
ConverterFactory
(3)在Spring MVC中使用ConversionService自定义转换器
3. 数据格式化
Spring3.0引入了一个新的格式化框架,位于org.springframework.format包中,
(1)Formatter<T>是格式化框架最重要的接口
(2)注解驱动格式化的重要接口
(3)启用注解驱动格式化功能
(4)注解驱动格式化实例
4. 数据校验
(1)JSR303是Java为Bean数据合法性校验所提供的标准框架,它已经包含在Java EE6.0中。通过在Bean属性上标注类似于@NotNull等标准的注解指定校验规则
(2)Spring校验框架,它在org.springframework.validation包下,通过注解驱动的方式进行数据校验。
(3)Spring数据校验(获取校验结果、如何在页面中显示错误、通过国际化资源显示错误信息)
(4)自定义校验规则(为请求处理类装配一个自定义的Validator)
五、视图和视图解析器
请求处理方法执行完成后,最终返回一个ModelAndView对象,对于那些String、View或ModelMap等类型的处理方法,SpringMVC也会在内部将它们装配成一个ModelAndView对象,它包含了实图逻辑名和模型对象的信息。
1. 视图,是渲染模型数据,将模型里的数据以某种形式呈现给客户(JSP、Excel、PDF等)。
2. 视图解析器,将逻辑视图名解析为一个具体的视图对象。
3. JSP和JSTL
(1)使用InternalResourceViewResolver作为视图解析器(JSP)
(2)使用Spring表单标签,它可以很容易地将模型数据中的表单/命令对象绑定到HTML表单元素中
4. 模板视图
FreeMarker和Velocity是除了JSP之外被使用最多的页面模板技术。页面模板编写好页面结构,模板页面中使用一些特殊的变量标识符绑定Java对象的动态数据。
5. Excel
如果希望使用Excel展示用户列表,仅需要扩展Spring的AbstractExcelView或AbstractJExcelView即可。
6. PDF
PDF视图和Excel类似,也是使用一个Bean作为视图对象
7. XML
将模型中的数据以XML的形式输出,对应视图对象为MarshallingView
8. JSON
SpringMVC的MappingJacksonJsonView借助Jackson框架的ObjectMapper将模型数据转换为JSON格式输出。
默认情况下,MappingJacksonJsonView会将模型中的所有数据都输出为JSON,这显然是不适合的,可以通过renderedAttravutes指定模型中哪些属性需要输出。
9. XmlViewResolver
同BeanNameViewResolver,但它可以将视图Bean定义在一个独立的XML文件中
10. ResourceBundleViewResolver
它通过一个国际化资源文件定义视图对象,为不同地区的用户提供不同类型的视图
11. 混合使用多种视图技术
(1)ContentNegotiatingViewResolver
(2)使用同一URL获取不同形式的返回内容
六、本地化解析
1. 本地化概述
浏览器中设置的本地化类型会包含在HTML请求报文头中发送给Web服务器,确切地说是通过报文头的Accept-Language参数将“语言首选项”对话框中选择的语言发送到服务器,成为服务器判别客户端本地化类型的依据。可以通过IE菜单:工具--Internet选项--语言--选择本地化类型设置。
2. 使用CookieLocaleResolver,DispactcherServlet会自动识别本地化解析器并装配它。
3. 使用SessionLocaleResolver,查找Session中属性名为SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME的属性,并将其转换为Locale对象。
4. 使用LocaleChangeInterceptor,通过一个请求参数控制网站的本地化。
七、文件上传
SpringMVC为文件上传提供了即插即用的MultipartResolver,采用了Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。
1. 配置MultipartResolver
<!-- 文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="UTF-8" p:maxUploadSize="5000000" p:uploadTempDir="upload/temp"/>
2. 编写控制器
@RequestMapping(value = "/upload") public String updateThumb(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) throws Exception{ if (!file.isEmpty()) { file.transferTo(new File("d:/temp/"+file.getOriginalFilename())); return "redirect:success.html"; }else{ return "redirect:fail.html"; } }
SpringMVC会将上传文件绑定到MultipartFile对象中。使用如下:
byte[] getBytes():获取文件数据
String getContentType():获取文件MIME类型
InputStream getInputStream():获取文件流
String getName():获取表单中文件组件的名字
String getOriginalFilename():获取上传文件的原名
long getSize():获取文件的字节大小,单位byte
boolean isEmpty():是否有上传的文件
void transferTo(File dest):将上传文件保存到一个目标文件中
3. 表单
负责上传文件的表单编码必须是“multipart/form-data”类型。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>请上传用户头像</title> </head> <body> <h1> 请选择上传的头像文件 </h1> <form method="post" action="<c:url value="/user/upload.html"/>" enctype="multipart/form-data"> <input type="text" name="name" /> <input type="file" name="file" /> <input type="submit" /> </form> </body> </html>
八、其它
1. 静态资源处理
(1)将DispatcherServlet请求映射配置为"/",使其捕获Web容器所有的请求。
<filter> <filter-name>Set Character Encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Set Character Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
(2)Spring MVC配置
方法一:
<!-- 如果是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,-->
<mvc:default-servlet-handler/>
方法二:
<!-- 由Spring MVC框架自己处理静态资源,将Web根路径“/”及类路径下/META-INF/publicResources/的目录映射为/resources路径。假设Web根路径下拥有js/ext.js,则在jsp则可通过 "/resources/js/ext.js访问" -->
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/publicResources/"/>
<mvc:resources/>允许静态资源放在任何地方,如WEB-INF目录下、类路径下等。在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303响应状态码,指示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端。如果在映射的物理路径下存在多个同名静态资源,找到第1个就返回,查找的顺序和物理路径在location中的配置顺序一致。
<mvc:resources mapping="/resources/**"
location="/" cache-period="31536000"/>
通过cache-period属性设置静态资源在客户端浏览器中的缓存有效时间,一般设置为一年。
有时由于浏览器本身缓存管理机制的问题,当我们发布新的版本时客户端并不会从服务器端下载新的静态资源。一个好的解决办法是:网页中引用静态资源的路径添加应用的发布版本号,这样由于版本号的变更造成网页中静态资源路径发生更改,从而使这些静态资源成为“新的资源”。下面将版本号包含到<mvc:resources/>中。
创建版本号获取类:
import javax.servlet.ServletContext; import org.springframework.web.context.ServletContextAware; public class ResourcePathExposer implements ServletContextAware { private ServletContext servletContext; private String resourceRoot; public void init() { String version = "1.2.1"; resourceRoot = "/resources-" + version; getServletContext().setAttribute("resourceRoot", getServletContext().getContextPath()+resourceRoot); } public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } public String getResourceRoot() { return resourceRoot; } public ServletContext getServletContext() { return servletContext; } }
在<mvc:resources/>中配置:
<bean id="rpe" class="com.baobaotao.web.ResourcePathExposer" init-method="init"/> <mvc:resources mapping="#{rpe.resourceRoot}/**" location="/" cache-period="31536000"/>
在jsp中引用路径:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>静态资源测试</title> <script src="${resourceRoot}/js/test.js" type="text/javascript"> </script> </head> <body> hello!! <script> test(); </script> </body> </html>
2. 异常处理
SpringMVC通过HandlerExceptionResolver处理程序的异常,包括处理器映射、数据绑定以及处理器执行时发生异常。
评论
4 楼
chiqinghaichi
2015-05-31
楼主好!菜鸟一枚,试了下你的程序,当访问 http://localhost/项目名/user/login.html
输入用户名和密码后提示,404错误。
输入用户名和密码后提示,404错误。
3 楼
随意而生
2015-03-12
复习复习 不错
2 楼
happy200318
2014-10-21
给个赞,不错
1 楼
cylboke
2014-10-21
总结的不错,赞
发表评论
-
Spring整合MyBatis
2014-05-15 00:43 3227首先介绍一下整合中用到的几个类 1)org.mybatis ... -
Spring整合Hibernate
2014-03-11 00:08 438就Hibernate的持久层访问技术而言,Spring提供 ... -
Spring整合Struts2
2014-03-11 00:08 4411.启动Spring容器 对于使用Spring的Web应用 ... -
Spring的事务管理
2014-03-10 23:34 474一、概述 Spring的事务管理不需要与任何特定的事务AP ... -
Spring
2014-03-10 21:40 1123一、Spring基础 1. Spring简介 Spring ...
相关推荐
Spring、SpringMVC和Mybatis是Java开发中最常用的三大开源框架,它们的整合使用,通常被称为SSM框架。这个框架组合提供了完整的后端服务解决方案,包括依赖注入(DI)、面向切面编程(AOP)、模型-视图-控制器(MVC...
SpringMVC是Spring框架的一个模块,专为构建Web应用程序提供模型-视图-控制器(MVC)架构。这个“springMVC练手代码”压缩包包含的资源可以帮助初学者或开发者深入了解并实践SpringMVC的基本操作和核心概念。 首先...
SpringMVC是一款强大的Java web开发框架,用于构建高效、可维护的Web应用程序。在这个"SpringMVC demo 完整源码实例下载"中,我们能够深入理解并学习SpringMVC的核心概念和实际应用。 首先,SpringMVC是Spring框架...
【狂神SpringMVC配套课程代码】一共8个模块,大概可以看我的博客,都是自己学配套整理的 欢迎大家作为学习SpringMVC的参考!! 下面附上狂神B站课程网址,和我的博客笔记(共8章) 狂神老师B站课程:...
SpringMVC是一个强大的Java Web开发框架,由Spring社区开发,它是Spring生态系统的重要组成部分,主要用于构建后端服务。SpringMVC以其灵活的配置、高度模块化和优秀的性能深受开发者喜爱。在这个"springmvc实战项目...
### SpringMVC基础知识详解 #### 一、SpringMVC简介 **SpringMVC**是Spring框架中的一个重要组成部分,主要用于Web应用程序的开发。它遵循MVC(Model-View-Controller)设计模式,帮助开发者构建清晰、可维护的Web...
SpringMVC 是一款基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的重要组成部分,主要用于构建 MVC(Model-View-Controller)模式的 Web 应用程序。本教程将深入探讨 SpringMVC 的核心概念、配置以及实际应用。...
本教程将详细阐述如何使用四个关键组件——Maven、SpringMVC、MyBatis和Log4j——来搭建一个强大的Web应用框架,旨在提高开发效率并优化项目管理。 **Maven** 是一个流行的项目管理和综合工具,它通过统一的构建...
【SpringMVC】 SpringMVC是Spring框架的一部分,它是一个用于构建Web应用程序的轻量级、模型-视图-控制器(MVC)架构。SpringMVC通过将业务逻辑、控制逻辑和显示逻辑分离,提高了代码的可维护性和可测试性。在...
SpringMVC、Hibernate和Spring是Java开发中三大核心框架,它们各自负责应用程序的不同层面:SpringMVC用于处理HTTP请求和响应,Hibernate则是持久层框架,负责数据库操作,而Spring作为全能容器,提供依赖注入和面向...
SpringMVC和MyBatis是Java Web开发中的两个核心框架,它们在构建高效、模块化的应用程序方面发挥着重要作用。SpringMVC是Spring框架的一部分,主要负责处理HTTP请求和响应,而MyBatis则是一个轻量级的持久层框架,...
**SpringMVC 入门小程序详解** SpringMVC是Spring框架的一个重要模块,它是一个用于构建Web应用程序的轻量级、模型-视图-控制器(MVC)框架。本入门程序旨在帮助初学者理解并掌握SpringMVC的基本概念和工作流程,...
SpringMVC 拦截器项目是一个典型的 Web 应用开发示例,它利用 SpringMVC 框架中的拦截器(Interceptor)机制来实现特定的功能,如权限控制、日志记录、性能统计等。SpringMVC 是 Spring 框架的一部分,专为构建基于 ...
《尚硅谷SpringMVC部分全套教学文档笔记》涵盖了SpringMVC框架的核心概念和技术,通过一系列章节深入浅出地讲解了SpringMVC的各个方面。以下是基于这些文档内容的详细知识点总结: 1. **SpringMVC概述与HelloWorld*...
SpringMVC是Spring框架的一部分,专门用于构建Web应用程序的模型-视图-控制器(MVC)架构。在本文中,我们将深入探讨SpringMVC 5.0版本的关键特性、使用方法以及它如何增强Web开发的效率。 首先,SpringMVC 5.0是...
Java基于Spring+SpringMVC+MyBatis实现的学生信息管理系统源码,SSM+Vue的学生管理系统。 Java基于Spring+SpringMVC+MyBatis实现的学生信息管理系统源码,SSM+Vue的学生管理系统。 Java基于Spring+SpringMVC+...
在本项目中,我们主要探讨的是如何将SpringMVC、MyBatis、PostgreSQL数据库以及Maven构建工具进行有效的整合,以实现一个高效且模块化的Web应用开发环境。以下是关于这些技术及其整合的关键知识点的详细说明: **1....
SpringMVC留言板是一个基于Java的Web应用程序,使用了SpringMVC框架来实现用户交互和数据管理。这个实验项目旨在帮助开发者了解如何在实际环境中运用SpringMVC,掌握其核心概念和工作流程。以下是对该实验项目的详细...