Microsoft Word - 扉页.doc

Similar documents
本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

untitled

在Spring中使用Kafka:Producer篇

在所有的项目开发中, 一定是多人协作的团队开发, 但是使用框架就会出现一个问题, 我们所 有的 Action 以及相关的路径都要求在我们的 struts.xml 文件中配置, 如果所有的人去修改一个 文件, 那么就会变得混乱, 而且有可能出现冲突, 那么在 struts.xml 文件中为了解决这个问

Stateless Session Beans(无状态bean)的学习

2. AOP 底层技术实现 小风 Java 实战系列教程 关键词 : 代理模式 代理模型分为两种 : 1) 接口代理 (JDK 动态代理 ) 2) 子类代理 (Cglib 子类代理 ) 需求 :CustomerService 业务类, 有 save,update 方法, 希望在 save,updat

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc

Microsoft Word - 01.DOC

新・解きながら学ぶJava

jsp

EJB-Programming-4-cn.doc

"+handlermethod.getbean().getclass().getname()); public void aftercompletion(httpservletrequest req, HttpServletResponse resp, Object handler, Excepti

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

EJB-Programming-3.PDF

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

无类继承.key

IoC容器和Dependency Injection模式.doc

CHAPTER 1

09 (File Processes) (mkdir) 9-3 (createnewfile) 9-4 (write) 9-5 (read) 9-6 (deletefile) 9-7 (deletedir) (Exercises)

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

本章学习目标 小风 Java 实战系列教程 Shiro 核心功能 Shiro 的 Web 集成 Spring 与 Shiro 整合 SpringBoot 整合 Shiro 1. Shiro 核心功能 1.1. RBAC 模型 在 RBAC 的模型, 涉及到三个关键的元素 : 1) 用户 : 系统的使

Guava学习之Resources

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

Microsoft Word - json入门.doc

導讀 ASP.NET HTML ASP 第一篇 基礎篇第 1 章 認識 ASP.NET ASP.NET ASP.NET ASP.NET ASP.NET 第 2 章 認識 Visual Studio 20 開發環境 Visual Studio 20 Visual Studio 20 第二篇 C# 程式

基于CDIO一体化理念的课程教学大纲设计

untitled

untitled

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

RUN_PC連載_10_.doc

《大话设计模式》第一章

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

05 01 accordion UI containers 03 Accordion accordion UI accordion 54

XXXXXXXX

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

3.1 num = 3 ch = 'C' 2

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

Microsoft Word - Learn Objective-C.doc

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款

使用MapReduce读取XML文件

RUN_PC連載_8_.doc

没 有 多 余 的 Contruol 或 Action 了 原 来 Domain 层 被 服 务 层 Service layer 遮 挡, 在 右 边 图 中, 则 Domain 层 直 接 暴 露 给 前 台 了, 没 有 被 遮 挡, 裸 露 了 这 样 一 步 到 位 实 现 领 域 模 型

5-1 nav css 5-2

Microsoft Word - PHP7Ch01.docx

1.2. Sql 映射配置 小风 Java 实战系列教程 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//dtd Mapper 3.0//EN" "

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

Chapter 9: Objects and Classes

1. 2. Flex Adobe 3.

untitled

關於本書 Part 3 CSS XHTML Ajax Part 4 HTML 5 API JavaScript HTML 5 API Canvas API ( ) Video/Audio API ( ) Drag and Drop API ( ) Geolocation API ( ) Part 5

javaexample-02.pdf

● 源起


拦截器(Interceptor)的学习

關於本書 l 3 PhoneGap Appcelerator Titanium Sencha Touch (wrapper framework) Native App PhoneGap Build Native App Hybrid App Java Objective-C Android SDK

<4D F736F F F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

优迈科技教学大纲2009版本

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复

new 进行创建对象, 是程序主动去创建依赖对象 ; 而 IoC 是有专门一个容器来创建这些对象, 即由 Ioc 容器来控制对象的创建 ; 谁控制谁? 当然是 IoC 容器控制了对象 ; 控制什么? 那就是主要控制了外部资源获取 ( 不只是对象包括比如文件等 ) 为何是反转, 哪些方面反转了 : 有

chapter 2 HTML5 目錄iii HTML HTML HTML HTML HTML canvas

LiveBOS产品白皮书

LiveBOS产品白皮书

Java

互動網頁技術系列課程 HTML與CSS網站基礎設計 [12pt]

Microsoft PowerPoint - ch6 [相容模式]

第一章 章标题-F2 上空24,下空24

创业板投资风险提示:本次股票发行后拟在创业板市场上市,该市场具有较高的投资风险

Microsoft Word - 第3章.doc

TWLOM060929

國家圖書館典藏電子全文

PowerPoint 演示文稿

在 ongodb 中实现强事务

附件2

<ADB6ADB1C25EA8FAA6DB2D4D56432E706466>

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

设计模式 Design Patterns

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

Chapter 9: Objects and Classes

untitled

1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F

基于ECO的UML模型驱动的数据库应用开发1.doc

Microsoft Word - Ch06.docx

060522達文西密碼_全_.PDF

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF

OSWorkflow Documentation

Java 1 Java String Date

设计模式 Design Patterns

声 明 本 公 司 及 全 体 董 事 监 事 高 级 管 理 人 员 承 诺 不 存 在 任 何 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏, 并 对 其 真 实 性 准 确 性 完 整 性 承 担 个 别 和 连 带 的 法 律 责 任 本 公 司 负 责 人 和 主 管 会 计 工

目 录 1. 业 务 流 程 系 统 开 发 面 临 的 挑 战 与 机 遇 业 务 流 程 管 理 新 一 代 开 源 业 务 流 程 开 发 平 台 BPMX BPMX3 是 什 么 为 什 么 要 优 先 采 用 BPMX

将 MD5 的工具类拷贝到项目中 二 微服务模块的搭建 我们将权限的查询放到一个单独的模块中, 这个模块提供接口供给消费者远程调用 (RPC), 这次范例是微服开发的雏形, 在以后你使用 springcloud 的时候会使用到今天的概念 1 使用 maven 创建新的模块 (microboot-sh

untitled

1. 访 问 最 新 发 行 公 告 信 息 jconnect for JDBC 访 问 最 新 发 行 公 告 信 息 最 新 版 本 的 发 行 公 告 可 以 从 网 上 获 得 若 要 查 找 在 本 产 品 发 布 后 增 加 的 重 要 产 品 或 文 档 信 息, 请 访

<!-- import outer proper

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

17 Chapter Video/Audio API 17-1 <video> <audio> 17-2 <video> <audio>

Struts2自定义类型转换.doc

D C 93 2

Transcription:

第 5 章 chapter 5 数据验证 学习目的与要求本章重点讲解 Spring MVC 框架的输入验证体系 通过本章的学习, 理解输入验证的流程, 能够利用 Spring 的自带验证框架和 JSR 303(Java 验证规范 ) 对数据进行验证 本章主要内容 数据验证概述 Spring 验证 JSR 303 验证所有用户的输入一般都是随意的, 为了保证数据的合法性, 数据验证是所有 Web 应用必须处理的问题 在 Spring MVC 框架中, 有两种方法可以验证输入数据 : 一是利用 Spring 自带的验证框架, 一是利用 JSR 303 实现 5.1 数据验证概述 数据验证分为客户端验证和服务器端验证, 客户端验证主要是过滤正常用户的误操作, 主要通过 JavaScript 代码完成 ; 服务器端验证是整个应用阻止非法数据的最后防线, 主要通过在应用中编程实现 5.1.1 客户端验证 大多数情况下, 使用 JavaScript 进行客户端验证的步骤如下 : (1) 编写验证函数 ; (2) 在提交表单的事件中调用验证函数 ; (3) 根据验证函数来判断是否进行表单提交 客户端验证可以过滤用户的误操作, 是第一道防线, 一般使用 JavaScript 代码实现 仅有客户端验证还是不够的 攻击者还可以绕过客户端验证直接进行非法输入, 这样可能会引起系统的异常, 为了确保数据的合法性, 防止用户通过非正常手段提交错误信息

第 5 章数据验证 71 所以必须加上服务器端的验证 5.1.2 服务器端验证 Spring MVC 的 Converter 和 Formatter 在进行类型转换时, 是将输入数据转换成领域对象的属性值 ( 一种 Java 类型 ), 一旦成功, 服务器端验证器就会介入 也就是说, 在 Spring MVC 框架中, 先进行数据类型转换, 再进行服务器端验证 服务器端验证对于系统的安全性 完整性 健壮性起到了至关重要的作用 在 Spring MVC 框架中, 可以利用 Spring 自带的验证框架验证数据, 也可以利用 JSR 303 实现数据验证 5.2 Spring 验证器 5.2.1 Validator 接口 创建自定义 Spring 验证器, 需要实现 org.springframework.validation.validator 接口 该接口有两个接口方法 : boolean supports(class<?> klass) void validate(object object, Errors errors) supports 方法返回 True 时, 验证器可以处理指定的 Class validate 方法的功能是验证目标对象 object, 并将验证错误消息存入 errors 对象 往 errors 对象存入错误消息的方法是 reject 或 rejectvalue 方法 这两个方法的部分重载方法如下 : void reject(string errorcode) void reject(string errorcode, String defaultmessage) void rejectvalue(string field, String errorcode) void rejectvalue(string field, String errorcode, String defaultmessage) 一般情况下, 只需要给 reject 或 rejectvalue 方法一个错误代码,Spring MVC 框架就会在消息属性文件中查找错误代码, 获取相应错误消息 具体示例如下 : if(goods.getgprice() > 100 goods.getgprice() < 0){ errors.rejectvalue("gprice", "gprice.invalid");//gprice.invalid // 为错误代码 5.2.2 ValidationUtils 类 org.springframework.validation.validationutils 是一个工具类, 该类中有几个方法可以

72 S pring MVC 开发技术指南 帮助判定值是否为空 例如 : if(goods.getgname() == null goods.getgname().isempty()){ errors.rejectvalue("gname", "goods.gname.required") 上述 if 语句可以使用 ValidationUtils 类的 rejectifempty 方法, 代码如下 : // errors 为 Errors 对象 // gname 为 goods 对象的属性 ValidationUtils.rejectIfEmpty(errors, "gname", "goods.gname.required"); 再如 : if(goods.getgname() == null goods.getgname().trim().isempty()){ errors.rejectvalue("gname", "goods.gname.required") 上述 if 语句可以编写成 : //gname 为 goods 对象的属性 ValidationUtils.rejectIfEmptyOrWhitespace(errors, "gname", "goods. gname.required"); 5.2.3 验证示例 本节使用一个应用 ch5a 讲解 Spring 验证器的编写及使用 ch5a 的项目结构如图 5.1 所示 图 5.1 ch5a 的项目结构

第 5 章数据验证 73 该应用中有个数据输入页面 addgoods.jsp, 效果如图 5.2 所示 ; 有个数据显示页面 goodslist.jsp, 效果如图 5.3 所示 图 5.2 数据输入页面图 5.3 数据显示页面 编写一个实现 org.springframework.validation.validator 接口的验证器类 GoodsValidator, 验证要求如下 : (1) 商品名和商品详情不能为空 (2) 商品价格在 0~100 之间 (3) 创建日期不能在系统日期之后 根据上述要求, 按照如下步骤完成应用 ch5a 1. 编写模型类 定义领域模型类 Goods, 封装输入参数 在该类中使用 @DateTimeFormat(pattern= "yyyy-mm-dd") 格式化创建日期 模型类 Goods 的具体代码如下 : package domain; import java.util.date; import org.springframework.format.annotation.datetimeformat; public class Goods { private String gname; private String gdescription; private double gprice; // 日期格式化 ( 需要在配置文件配置 FormattingConversionServiceFactoryBean) @DateTimeFormat(pattern="yyyy-MM-dd") private Date gdate; public String getgname() { return gname; public void setgname(string gname) { this.gname = gname; public String getgdescription() { return gdescription;

74 S pring MVC 开发技术指南 public void setgdescription(string gdescription) { this.gdescription = gdescription; public double getgprice() { return gprice; public void setgprice(double gprice) { this.gprice = gprice; public Date getgdate() { return gdate; public void setgdate(date gdate) { this.gdate = gdate; 2. 编写验证器类 编写实现 org.springframework.validation.validator 接口的验证器类 GoodsValidator, 使用 @Component 注解将 GoodsValidator 类声明为组件 具体代码如下 : package validator; import java.util.date; import org.springframework.stereotype.component; import org.springframework.validation.errors; import org.springframework.validation.validationutils; import org.springframework.validation.validator; import domain.goods; @Component public class GoodsValidator implements Validator{ @Override public boolean supports(class<?> klass) { // 要验证的 Model, 返回值为 False 则不验证 return Goods.class.isAssignableFrom(klass); @Override public void validate(object object, Errors errors) { Goods goods = (Goods)object;//object 要验证的对象 //goods.gname.required 是错误消息属性文件中的编码 ( 国际化后, 对应的是国际化的信息 ) ValidationUtils.rejectIfEmpty(errors, "gname", "goods.gname.required"); ValidationUtils.rejectIfEmpty(errors, "gdescription", "goods.gdescription.required"); if(goods.getgprice() > 100 goods.getgprice() < 0){

第 5 章数据验证 75 errors.rejectvalue("gprice", "gprice.invalid"); Date goodsdate = goods.getgdate(); // 在系统时间之后 if(goodsdate!= null && goodsdate.after(new Date())){ errors.rejectvalue("gdate", "gdate.invalid"); 3. 编写错误消息属性文件 在 /WEB-INF/resource 目录下, 编写属性文件 errormessages.properties 文件内容如下 : goods.gname.required= 请输入商品名称 goods.gdescription.required= 请输入商品详情 gprice.invalid= 价格在 0~100 之间 gdate.invalid= 创建日期不能在系统日期之后 Unicode 编码 (Eclipse 带有将汉字转换成 Unicode 编码的功能 ) 的属性文件内容如下 : goods.gname.required=\u8bf7\u8f93\u5165\u5546\u54c1\u540d\u79f0\u3002 goods.gdescription.required=\u8bf7\u8f93\u5165\u5546\u54c1\u8be6\u60c5 \u3002 gprice.invalid=\u4ef7\u683c\u57280-100\u4e4b\u95f4\u3002 gdate.invalid=\u521b\u5efa\u65e5\u671f\u4e0d\u80fd\u5728\u7cfb\u7edf\u 65E5\u671F\u4E4B\u540E\u3002 属性文件创建完成后, 想要告诉 Spring MVC 从该文件中获取错误消息, 则需要在配置文件中声明一个 messagesource bean, 具体代码如下 : <!-- 配置消息属性文件 --> <bean id="messagesource" class="org.springframework.context.support.reloadableresource_ BundleMessageSource"> <property name="basename" value="/web-inf/resource/error Messages"/> </bean> 4. 编写 Service 层 在 Service 层中编写一个 GoodsService 接口和 GoodsServiceImpl 实现类 具体代码如下 : package service; import java.util.arraylist; import domain.goods; public interface GoodsService {

76 S pring MVC 开发技术指南 boolean save(goods g); ArrayList<Goods> getgoods(); package service; import java.util.arraylist; import org.springframework.stereotype.service; import domain.goods; @Service public class GoodsServiceImpl implements GoodsService{ // 使用静态集合变量 users 模拟数据库 private static ArrayList<Goods> goods = new ArrayList<Goods>(); @Override public boolean save(goods g) { goods.add(g); return true; @Override public ArrayList<Goods> getgoods() { return goods; 5. 编写控制器类 编写控制器类 GoodsController, 在该类中使用 @Resource 注解注入自定义验证器 另外, 控制器类中包含两个处理请求的方法, 具体代码如下 : package controller; import javax.annotation.resource; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.model; import org.springframework.validation.bindingresult; import org.springframework.validation.validator; import org.springframework.web.bind.annotation.modelattribute; import org.springframework.web.bind.annotation.requestmapping; import domain.goods; import service.goodsservice; @Controller @RequestMapping("/goods") public class GoodsController { // 得到一个用来记录日志的对象, 这样打印信息的时候能够标记打印的是哪个类的信息 private static final Log logger = LogFactory.getLog(GoodsController. class);

第 5 章数据验证 77 @Autowired private GoodsService goodsservice; // 注解验证器相当于 GoodsValidator validator = new GoodsValidator(); @Resource private Validator validator; @RequestMapping("/input") public String input(model model){ // 如果 model 中没有 goods 属性,addGoods.jsp 会抛出异常, // 因为表单标签无法找到 modelattribute 属性指定的 form // backing object model.addattribute("goods", new Goods()); return "addgoods"; @RequestMapping("/save") public String save(@modelattribute Goods goods, BindingResult result, Model model){ this.validator.validate(goods, result);// 添加验证 if (result.haserrors()) { return "addgoods"; goodsservice.save(goods); logger.info(" 添加成功 "); model.addattribute("goodslist", goodsservice.getgoods()); return "goodslist"; 6. 编写配置文件 配置文件 springmvc-servlet.xml 的代码如下 : <?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用扫描机制, 扫描包 --> <context:component-scan base-package="controller"/> <context:component-scan base-package="service"/>

78 S pring MVC 开发技术指南 <context:component-scan base-package="validator"/> <!-- 注册格式化转换器 --> <bean id="conversionservice" class="org.springframework.format. support.formattingconversionservicefactorybean"> <property name="formatters"> <set> <!-- 注册自定义格式化转换器 --> </set> </property> </bean> <mvc:annotation-driven conversion-service="conversionservice"/> <!-- 配置消息属性文件 --> <bean id="messagesource" class="org.springframework.context.support. ReloadableResourceBundleMessageSource"> <property name="basename" value="/web-inf/resource/errormessages"/> </bean> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.internalresource_ ViewResolver" id="internalresourceviewresolver"> <!-- 前缀 --> <property name="prefix" value="/web-inf/jsp/" /> <!-- 后缀 --> <property name="suffix" value=".jsp" /> </bean> </beans> 7. 编写视图 JSP 文件 应用 ch5a 中有两个视图文件 :addgoods.jsp 和 goodslist.jsp addgoods.jsp 的代码如下 : <%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <% String path = request.getcontextpath(); String basepath = request.getscheme()+"://"+request.getservername()+":"+ request.getserverport()+path+"/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <base href="<%=basepath%>"> <meta http-equiv="content-type" content="text/html; charset=utf-8">

第 5 章数据验证 79 <title>insert title here</title> </head> <body> <form:form modelattribute="goods" action="goods/save" method="post"> <fieldset> <legend> 添加一件商品 </legend> <p> <label> 商品名 :</label> <form:input path="gname"/> </p> <p> <label> 商品详情 :</label> <form:input path="gdescription"/> </p> <p> <label> 商品价格 :</label> <form:input path="gprice"/> </p> <p> <label> 创建日期 :</label> <form:input path="gdate"/>(yyyy-mm-dd) </p> <p id="buttons"> <input id="reset" type="reset"> <input id="submit" type="submit" value=" 添加 "> </p> </fieldset> <!-- 取出所有验证错误 --> <form:errors path="*"/> </form:form> </body> </html> goodslist.jsp 的代码如下 : <%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% String path = request.getcontextpath(); String basepath = request.getscheme()+"://"+request.getservername()+":"+ request.getserverport()+path+"/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html>