springmvc教程系列

springmvc史上最好教程(2)

springmvc史上最好教程(1)

springmvc史上最好教程(3)

2注解开发-高级

2.1上传图片

2.1.1配置虚拟目录

2.1.2配置解析器

<!-- 文件上传 --><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 设置上传文件的最大尺寸为5MB --><property name="maxUploadSize"><value>5242880</value></property></bean>

2.1.3jar包

CommonsMultipartResolver解析器依赖commons-fileupload和commons-io,加入如下jar包:

2.1.4单个图片上传

1、controller:

//商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{//原始文件名称String pictureFile_name =  pictureFile.getOriginalFilename();//新文件名称String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));//上传图片File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);if(!uploadPic.exists()){uploadPic.mkdirs();}//向磁盘写文件pictureFile.transferTo(uploadPic);.....

2、 页面:

form添加enctype="multipart/form-data":

<form id="itemForm"action="${pageContext.request.contextPath }/item/editItemSubmit.action"method="post" enctype="multipart/form-data"><input type="hidden" name="pic" value="${item.pic }" />

file的name与controller形参一致:

<tr><td>商品图片</td><td><c:if test="${item.pic !=null}"><img src="/pic/${item.pic}" width=100 height=100 /><br /></c:if> <input type="file" name="pictureFile" /></td></tr>

2.2Validation(了解)

b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,本节主要学习springmvc实现控制层添加校验。

Spring3支持JSR-303验证框架,JSR-303是JAVA EE 6中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator(与Hibernate ORM没有关系),JSR 303用于对Java Bean中的字段的值进行验证。

2.2.1需求

对商品信息进行校验,是否必须,输入数据合法性。

2.2.2加入jar包

2.2.3配置validator

<!-- 校验错误信息配置文件 --><bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basenames">   <list>    <value>classpath:CustomValidationMessages</value>   </list>   </property><property name="fileEncodings" value="utf-8" /><property name="cacheSeconds" value="120" /></bean><bean id="validator"class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"><property name="providerClass" value="org.hibernate.validator.HibernateValidator" /><!-- 如果不指定则默认使用classpath下的ValidationMessages.properties --><property name="validationMessageSource" ref="messageSource" /></bean>

2.2.4将validator加到处理器适配器

配置方式1:

<!-- 自定义webBinder --><bean id="customBinder"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><property name="validator" ref="validator" /></bean>
<!-- 注解适配器 --><beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="webBindingInitializer" ref="customBinder"></property></bean>

配置方式2:

<mvc:annotation-driven validator="validator"> </mvc:annotation-driven>

2.2.5添加验证规则

public class Items {private Integer id;@Size(min=1,max=30,message="{item.name.length.illigel}")private String name;@NotEmpty(message="{pic.is.null}")private String pic;

2.2.6错误消息文件CustomValidationMessages

item.name.length.illigel=商品在名称在1到3个字符之间

pic.is.null=请上传图片

如果在eclipse中编辑properties文件无法看到中文则参考“Eclipse开发环境配置-indigo.docx”添加propedit插件。

2.2.7捕获错误

修改Controller方法:

// 商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(@Validated @ModelAttribute("item") Items items,BindingResult result,@RequestParam("pictureFile") MultipartFile[] pictureFile,Model model)throws Exception {//如果存在校验错误则转到商品修改页面if (result.hasErrors()) {List<ObjectError> errors = result.getAllErrors();for(ObjectError objectError:errors){System.out.println(objectError.getCode());System.out.println(objectError.getDefaultMessage());}return "item/editItem";}

注意:添加@Validated表示在对items参数绑定时进行校验,校验信息写入BindingResult中,在要校验的pojo后边添加BingdingResult, 一个BindingResult对应一个pojo,且BingdingResult放在pojo的后边。

商品修改页面:

页头:

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

在需要显示错误信息地方:

<spring:hasBindErrors name="item"><c:forEach items="${errors.allErrors}" var="error">${error.defaultMessage }<br/></c:forEach></spring:hasBindErrors>

说明:

<spring:hasBindErrors name="item">表示如果item参数绑定校验错误下边显示错误信息。

2.2.8分组校验

如果两处校验使用同一个Items类则可以设定校验分组。

定义分组:

分组就是一个标识,这里定义一个接口:

public interface ValidGroup1 {}public interface ValidGroup2 {}

指定分组校验:

public class Items {private Integer id;//这里指定分组ValidGroup1,此@Size校验只适用ValidGroup1校验@Size(min=1,max=30,message="{item.name.length.illigel}",groups={ValidGroup1.class})private String name;// 商品修改提交@RequestMapping("/editItemSubmit")public String editItemSubmit(@Validated(value={ValidGroup1.class}) @ModelAttribute("item") Items items,BindingResult result,@RequestParam("pictureFile") MultipartFile[] pictureFile,Model model)throws Exception {

在@Validated中添加value={ValidGroup1.class}表示商品修改使用了ValidGroup1分组校验规则,也可以指定多个分组中间用逗号分隔,

@Validated(value={ValidGroup1.class,ValidGroup2.class})

2.3异常处理器

springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

2.3.1异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

2.3.2自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

 public class CustomException extends Exception {/** serialVersionUID*/private static final long serialVersionUID = -5212079010855161498L;public CustomException(String message){super(message);this.message = message;}//异常信息private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}

2.3.3自定义异常处理器

public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {ex.printStackTrace();CustomException customException = null;//如果抛出的是系统自定义异常则直接转换if(ex instanceof CustomException){customException = (CustomException)ex;}else{//如果抛出的不是系统自定义异常则重新构造一个未知错误异常。customException = new CustomException("未知错误,请与系统管理 员联系!");}ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("message", customException.getMessage());modelAndView.setViewName("error");return modelAndView;}}

2.3.4错误页面

 <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> <!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=UTF-8"><title>错误页面</title></head><body>您的操作出现错误如下:<br/>${message }</body></html>

2.3.5异常处理器配置

在springmvc.xml中添加:

<!-- 异常处理器 --><bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>

2.3.6异常测试

修改商品信息,id输入错误提示商品信息不存在。

修改controller方法“editItem”,调用service查询商品信息,如果商品信息为空则抛出异常:

// 调用service查询商品信息Items item = itemService.findItemById(id);if(item == null){throw new CustomException("商品信息不存在!");}

请自行实现在service、dao中跑出异常。

2.4json数据交互

2.4.1@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象

2.4.2@ResponseBody

作用:

该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

本例子应用:

@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端

2.4.3请求json,响应json实现:

2.4.3.1环境准备

Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包,如下:

2.4.3.2配置json转换器

在注解适配器中加入messageConverters

<!--注解适配器 --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean></list></property></bean>

注意:如果使用<mvc:annotation-driven />则不用定义上边的内容。

2.4.3.3controller编写

// 商品修改提交json信息,响应json信息@RequestMapping("/editItemSubmit_RequestJson")public @ResponseBody Items editItemSubmit_RequestJson(@RequestBody Items items) throws Exception {System.out.println(items);//itemService.saveItem(items);return items;}

2.4.3.4页面js方法编写:

引入 js:

<script type="text/javascript"

src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>

//请求json响应jsonfunction request_json(){$.ajax({type:"post",url:"${pageContext.request.contextPath }/item/editItemSubmit_RequestJson.action",contentType:"application/json;charset=utf-8",data:'{"name":"测试商品","price":99.9}',success:function(data){alert(data);}});}

2.4.3.5测试结果:

从上图可以看出请求的数据是json格式

2.4.4Form提交,响应json实现:

采用form提交是最常用的作法,通常有post和get两种方法,响应json数据是为了方便客户端处理,实现如下:

2.4.4.1环境准备

同第一个例子

2.4.4.2controller编写

// 商品修改提交,提交普通form表单数据,响应json@RequestMapping("/editItemSubmit_ResponseJson")public @ResponseBody Items editItemSubmit_ResponseJson(Items items) throws Exception {System.out.println(items);//itemService.saveItem(items);return items;}

2.4.4.3页面js方法编写:

function formsubmit(){var user = " name=测试商品&price=99.9";alert(user);$.ajax({type:'post',//这里改为get也可以正常执行url:'${pageContext.request.contextPath}/item/ editItemSubmit_RequestJson.action',//ContentType没指定将默认为:application/x-www-form-urlencodeddata:user,success:function(data){alert(data.name);}})}

从上边的js代码看出,已去掉ContentType的定义,ContentType默认为:application/x-www-form-urlencoded格式。

2.4.4.4测试结果:

从上图可以看出请求的数据是标准的key/value格式。

2.4.4.5jquery的form插件插件

针对上边第二种方法,可以使用jquery的form插件提交form表单,实现ajax提交form表单,如下:

引用js:

<script type="text/javascript"

src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>

<script type="text/javascript"

src="${pageContext.request.contextPath }/js/jquery.form.min.js"></script>

js方法如下:

function response_json() {//form对象var formObj = $("#itemForm");//执行ajax提交formObj.ajaxSubmit({dataType : "json",//设置预期服务端返回jsonsuccess : function(responseText) {alert(responseText);}});}

2.4.5小结

实际开发中常用第二种方法,请求key/value数据,响应json结果,方便客户端对结果进行解析。

2.5RESTful支持

2.5.1需求

RESTful方式商品修改、商品查询。

2.5.2添加DispatcherServlet的rest配置

<servlet><servlet-name>springmvc-servlet-rest</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/springmvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>springmvc-servlet-rest</servlet-name><url-pattern>/</url-pattern></servlet-mapping>

2.5.3URL模板模式映射

@RequestMapping(value="/editItem/{item_id}"):{×××}占位符,请求的URL可以是“/editItem/1”或“/editItem/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。

@RequestMapping("/ editItem/{item_id}") public String useredit(@PathVariable("item_id ") String id,Model model) throws Exception{//方法中使用@PathVariable获取useried的值,使用model传回页面model.addAttribute("userid", userid);return"/user/useredit";}

如果RequestMapping中表示为"/editItem/{id}",id和形参名称一致,@PathVariable不用指定名称。

商品查询的controller方法也改为rest实现:

// 查询商品列表@RequestMapping("/queryItem")public ModelAndView queryItem() throws Exception {// 商品列表List<Items> itemsList = itemService.findItemsList(null);// 创建modelAndView准备填充数据、设置视图ModelAndView modelAndView = new ModelAndView();// 填充数据modelAndView.addObject("itemsList", itemsList);// 视图modelAndView.setViewName("item/itemsList");return modelAndView;}

2.5.4静态资源访问<mvc:resources>

spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。

如下是对js文件访问配置:

<mvc:resources location="/js/" mapping="/js/**"/>

3拦截器

3.1定义

Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

3.2拦截器定义

实现HandlerInterceptor接口,如下:

Public class HandlerInterceptor1 implements HandlerInterceptor{/*** controller执行前调用此方法* 返回true表示继续执行,返回false中止执行* 这里可以加入登录校验、权限拦截等*/@OverridePublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {// TODO Auto-generated method stubReturn false;}/*** controller执行后但未返回视图前调用此方法* 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示*/@OverridePublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// TODO Auto-generated method stub}/*** controller执行后且视图返回后调用此方法* 这里可得到执行controller时的异常信息* 这里可记录操作日志,资源清理等*/@OverridePublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stub}}

3.3拦截器配置

3.3.1针对某种mapping配置拦截器

<beanclass="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"><property name="interceptors"><list><ref bean="handlerInterceptor1"/><ref bean="handlerInterceptor2"/></list></property></bean><bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/><bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

3.3.2针对所有mapping配置全局拦截器

 <!--拦截器 --><mvc:interceptors><!--多个拦截器,顺序执行 --><mvc:interceptor><mvc:mapping path="/**"/><bean class="cn.itcast.springmvc.filter.HandlerInterceptor1"></bean></mvc:interceptor><mvc:interceptor><mvc:mapping path="/**"/><bean class="cn.itcast.springmvc.filter.HandlerInterceptor2"></bean></mvc:interceptor></mvc:interceptors>

3.4正常流程测试

3.4.1代码:

定义两个拦截器分别为:HandlerInterceptor1和HandlerInteptor2,每个拦截器的preHandler方法都返回true。

3.4.2运行流程

HandlerInterceptor1..preHandle..

HandlerInterceptor2..preHandle..

HandlerInterceptor2..postHandle..

HandlerInterceptor1..postHandle..

HandlerInterceptor2..afterCompletion..

HandlerInterceptor1..afterCompletion..

3.5中断流程测试

3.5.1代码:

定义两个拦截器分别为:HandlerInterceptor1和HandlerInteptor2。

3.5.2运行流程

HandlerInterceptor1的preHandler方法返回false,HandlerInterceptor2返回true,运行流程如下:

HandlerInterceptor1..preHandle..

从日志看出第一个拦截器的preHandler方法返回false后第一个拦截器只执行了preHandler方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且controller也不执行了。

HandlerInterceptor1的preHandler方法返回true,HandlerInterceptor2返回false,运行流程如下:

HandlerInterceptor1..preHandle..

HandlerInterceptor2..preHandle..

HandlerInterceptor1..afterCompletion..

从日志看出第二个拦截器的preHandler方法返回false后第一个拦截器的postHandler没有执行,第二个拦截器的postHandler和afterCompletion没有执行,且controller也不执行了。

总结:

preHandle按拦截器定义顺序调用

postHandler按拦截器定义逆序调用

afterCompletion按拦截器定义逆序调用

postHandler在拦截器链内所有拦截器返成功调用

afterCompletion只有preHandle返回true才调用

3.6拦截器应用

3.6.1用户身份认证

Public class LoginInterceptorimplements HandlerInterceptor{@OverridePublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler)throws Exception {//如果是登录页面则放行if(request.getRequestURI().indexOf("login.action")>=0){return true;}HttpSession session = request.getSession();//如果用户已登录也放行if(session.getAttribute("user")!=null){return true;}//用户没有登录挑战到登录页面request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);return false;}}

3.6.2用户登陆controller

//登陆页面@RequestMapping("/login")public String login(Model model)throws Exception{return "login";}//登陆提交//userid:用户账号,pwd:密码@RequestMapping("/loginsubmit")public String loginsubmit(HttpSession session,String userid,String pwd)throws Exception{//向session记录用户身份信息session.setAttribute("activeUser", userid);return "redirect:item/queryItem.action";}//退出@RequestMapping("/logout")public String logout(HttpSession session)throws Exception{//session过期session.invalidate();return "redirect:item/queryItem.action";}

springmvc教程(4)相关推荐

  1. springmvc教程--注解开发基础详解

    springmvc教程系列 springmvc史上最好教程(2) springmvc史上最好教程(1) 一. 注解开发-基础 1.1 需求 使用springmvc+mybatis架构实现商品信息维护. ...

  2. springmvc教程(3)

    springmvc教程系列 springmvc史上最好教程(2) springmvc史上最好教程(1) 一. 注解开发-基础 1.1需求 使用springmvc+mybatis架构实现商品信息维护. ...

  3. springmvc教程(2)

    springmvc教程系列 springmvc史上最好教程(3) springmvc史上最好教程(1) 一.整合mybatis 为了更好的学习 springmvc和mybatis整合开发的方法,需要将 ...

  4. springmvc教程--快速入门教程

    springmvc教程系列: springmvc史上最好教程(3) springmvc史上最好教程(2) 一. SpringMVC架构 1.1. Spring web mvc介绍 Spring web ...

  5. springmvc教程(1)

    springmvc教程系列: springmvc史上最好教程(3) springmvc史上最好教程(2) 一. SpringMVC架构 1.1. Spring web mvc介绍 Spring web ...

  6. spring-mvc教程_使用MVC模式制作游戏-教程和简介

    spring-mvc教程 游戏开发中一种有用的体系结构模式是MVC(模型视图控制器)模式. 它有助于分离输入逻辑,游戏逻辑和UI(渲染). 在任何游戏开发项目的早期阶段,它的用途很快就会被注意到,因为 ...

  7. SpringMVC教程下篇

    SpringMVC教程下篇 内容包括: 绑定数组: 将表单数据绑定到list: @RequestMapping注解的三种用法: Controller方法返回值: 乱码问题总结 异常处理: 照片上传: ...

  8. SpringMVC教程上篇

    SpringMVC教程上篇 SpringMVC优势: SpringMVC代码执行流程: 框架结构: 架构流程: 组件说明: SpringMVC与Mybatis整合 ! 效果: 开发流程:

  9. 最全面的SpringMVC教程(六)——WebSocket

    前言 本文为 [SpringMVC教程]WebSocket 相关知识介绍,具体将对WebSocket进行简介,并通过实战案例对WebSocket的使用进行详尽介绍~

最新文章

  1. Storm的StreamID使用样例(版本1.0.2)
  2. Redhat 6.4_联网 yum 配置
  3. 二叉堆详解实现优先级队列
  4. MyBatisPlus(基于starter和Bean方式)
  5. 3招seo技巧让你把关键词做进百度前三
  6. 为什么劝你放弃Maven?看看Gradle的这些优点就知道了
  7. UI实用素材模板|可临摹学习的控制面板
  8. SCPPO(二十):系统统一身份认证的改造之路
  9. linux内存管理实验,Linux内存管理机制研究
  10. Java学习笔记之StringBuilder类
  11. flame linux mac,Autodesk版蓝宝石插件 GenArts Sapphire V10.0 (Mac/Linux)
  12. canvas 实现图片添加水印
  13. 责任链模式实现及在Filter中的应用
  14. 微信小程序海报画布生成圆形头像
  15. 【厄舍府的倒塌】超脱
  16. 养育女孩(成长版)点燃孩子兴趣的火花
  17. ctp linux 查询死循环,CTP行情接入常见的问题记录
  18. 设计模式(Java)----装饰模式Decorator
  19. Invictus -- 不可征服
  20. linux内核添加spi驱动,Linux内核驱动之spi子系统spi协议.docx

热门文章

  1. getaddrinfo函数
  2. AB1601低功耗之IIC和PWM控制注意事项
  3. BLE-NRF51822教程11-手机动态修改设备名
  4. 强化学习(四)—— Actor-Critic
  5. C++ Primer 5th笔记(chap 16 模板和泛型编程)重载与模板
  6. (chap8 确认访问用户身份的认证) DIGES认证(摘要认证)
  7. MTK:oemlock介绍
  8. (72)进程挂靠(attach)使用备用APC队列 SavedApcState 保存父进程 APC 队列,分析 NtReadVirtualMemory
  9. 【安全漏洞】深入剖析CVE-2021-40444-Cabless利用链
  10. 透露抖音、腾讯、阿里、美团招开发岗位硬核面试题,轻轻松松收到offer