- 浏览: 186710 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
di1984HIT:
记录一下。嘿嘿
eclipse中关闭js报错的方法 -
di1984HIT:
谢谢,学习了
jdk输出带缩进格式xml的方法 -
雪狐狼:
为何,每次查询需要 构建datatable?
YUI DataTable 服务器端翻页与排序 -
lijunwyf41:
nd:"nd", // 表示已经发送请求的 ...
jqGrid <-- json --> spring,hibernate之服务器端分页,排序 -
yiyu:
最近不看YUI了,发现一个国产的前端框架,是金蝶出的,叫Ope ...
YUI 3 学习笔记(5)- Attribute类
前一段试了一下前台用jquery(1.3.2),后台用spring(3.0),之间用json交换数据,
然后写了篇总结jquery(1.3.2)<--json-->spring(3.0),有几位大侠提出了后台校验
的问题,我也觉得这是很普遍的问题,就参考一些资料做了个小demo,现在总结一下,
欢迎各位拍砖。
我是这样考虑的,在后台接收数据时,首先使用一个所有属性均为String的对象,在
这个对象上,使用Bean Validation(JSR-303)进行数据校验,校验通过后,再将该对象
转换为一个VO然后进行后续处理,在校验充分的情况下,转换步骤是不会出现例外的。
在校验失败的时候,返回由属性名(也即页面元素名)、错误信息对组成的数组,前端
根据元素名自动突出显示对应元素、并在其旁边显示错误信息,下面详细说明。
1. 前端提交
这和前文一样,没什么可说的。
2. 后台校验
2.1 属性全为String的对象,及其校验
spring 3开始全面支持JSR-303,并以hibernate validator作为默认实现,该技术可以
用声明(Annotaion)的方式定义校验,而且标记可以自由扩充,我觉得这很方便,所以
用的这一技术做的校验。
后台所有接收的对象都为全String类型属性对象,因为对于json数据传输我们无法在接收
数据之前进行校验,属性全用String可以避免在Controller获取数据前发生数据转换错误。
JSR-303内建了一些校验规则,例如Min,Max,Pattern(正则表达式,有了这个就可以
处理绝大部分校验了),hibernate validtor还扩充了NotEmpty,Email等,一下是我的
例子中客户信息的对象:
package json; import javax.validation.constraints.Digits; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.Email; import constraints.IsDate; public class JSONCustomer { @NotEmpty private String name; @NotEmpty private String addr; @NotEmpty @IsDate(format="yyyy-MM-dd") private String birthday; @NotEmpty private String hukou; @Email private String email; @Pattern(regexp="(((\\w+)\\.)+(\\w+))?") private String url; @Digits(integer = 3, fraction = 0) @Min(value = 100) @Max(value = 230) private String height; //setter, getter略 }
其中IsDate是我自己扩充的校验Annotation,这个后面再说。
这样,校验就定义好了,简单吧。
2.2 校验
下面来看看Controller中的校验。首先要在Controller的构造函数中传入validator,
spring有默认的validator,就是hibennate validator 4(所以需要这个jar包)。
然后在处理函数中使用validator.validate()就可以了,代码如下:
package controller; import java.lang.reflect.InvocationTargetException; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.apache.commons.beanutils.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import json.JSONCustomer; import json.JSONResponse; import vo.Customer; @Controller @RequestMapping("/customerInfo") public class CustomerInfoController extends JSONController { @Autowired public CustomerInfoController(Validator validator) { super(validator); } @RequestMapping(value = "/new", method = RequestMethod.POST) @ResponseBody public JSONResponse newCustomer(@RequestBody JSONCustomer jsoncustomer) throws IllegalAccessException, InvocationTargetException { Set<ConstraintViolation<JSONCustomer>> failures = validator.validate(jsoncustomer); if (failures.isEmpty()) { //校验通过 Customer customer = new Customer(); //将接收的全String属性对象转成vo BeanUtils.copyProperties(jsoncustomer, customer); return successed(jsoncustomer); } else { //校验失败 return failed(failures); } } }
其中JSONController是我自己的Controller基类,后面再说。根据validate()的返回值failures
可以知道是否通过了校验,successed()和failed()是JSONController的方法,为了统一成功与
失败时的返回数据格式,这个在后面说明。
2.3 自定义校验Annotation
这部分请参阅相关的文档,我就不多说了,这里只贴出代码:
package constraints; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Target( { METHOD, FIELD, ANNOTATION_TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = IsDateValidator.class) @Documented public @interface IsDate { String message() default "日期格式不正确"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; String format(); }
package constraints; import java.text.ParseException; import java.text.SimpleDateFormat; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class IsDateValidator implements ConstraintValidator<IsDate, String> { private String format; public void initialize(IsDate constraintAnnotation) { this.format = constraintAnnotation.format(); } public boolean isValid(String object, ConstraintValidatorContext constraintContext) { try { SimpleDateFormat sf = new SimpleDateFormat(format); sf.setLenient(false); sf.parse((String)object); return true; } catch (ParseException pe) { return false; } } }
有了内建的校验和自定义校验的功能,我们就可以实现所有的校验了。而且校验的错误信息
是可以自定义的。校验施加的对象也可以是属性、方法、甚至对象整体,就是说可以根据对
象的多个属性值判断进行校验,详细的请参考jsr-303和其推荐实现hibernate validator的
相关文档。
3. 返回值
3.1 返回的对象结构
为了统一页面端的处理,后台返回值具有统一的结构,定义如下:
package json; import java.util.ArrayList; /** * 服务器返回对象 * 所有服务器处理返回的统一对象 */ public class JSONResponse { //成功、失败标志 private boolean successed = false; //错误信息 private ArrayList<JSONError> errors = null; //成功时返回的对象 private Object returnObject = null; //setter, getter略 }
其中JSONError定义如下:
package json; /** * 错误信息 * */ public class JSONError { //元素名,与页面元素名一致 private String element; //错误信息 private String message; //setter, getter略 }
成功时,successed=true,返回的对象在returnObject中,对于不同页面,这个
对象是不同的,但各个页面知道自己要得到一个什么结构的数据。校验失败时
successed=false,errors是一个数组,其中每个元素是一个<元素名-错误信息>对。
3.2 返回方法
返回的方法是统一的,定义在JSONController里,代码如下:
package controller; import java.util.ArrayList; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validator; import json.JSONError; import json.JSONResponse; public class JSONController { protected Validator validator; public JSONController(Validator validator) { this.validator = validator; } public JSONResponse successed(Object obj) { JSONResponse ret = new JSONResponse(); ret.setSuccessed(true); ret.setReturnObject(obj); return ret; } public JSONResponse failed(Set failures) { Set<ConstraintViolation<?>> failureSet = (Set<ConstraintViolation<?>>)failures; ArrayList<JSONError> errors = new ArrayList<JSONError>(); for (ConstraintViolation<?> failure : failureSet) { errors.add(new JSONError(failure.getPropertyPath().toString(), failure.getMessage())); } JSONResponse ret = new JSONResponse(); ret.setSuccessed(false); ret.setErrors(errors); return ret; } }
4. 页面处理
页面的html主要就是一个包含姓名、地址、生日、Email、身高等输入项的form,这里就
不贴出来丢人了,需要说明的是每个输入项后都有一个<div class="errorMessage"></div>
准备放错误信息。
页面以json格式接收后台的处理结果,如果结果标识成功,则对返回的对象进行处理(显
示之类的,这里没有涉及),如果标识失败,则根据错误信息进行处理。
其中提交数据的处理代码如下:
function save() { var elemUserinfo = $('#customerInfo'); var userinfo = elemUserinfo.serializeObject(); var jsonuserinfo = JSON.stringify(userinfo); jQuery.ajax( { type : 'POST', contentType : 'application/json', url : 'customerInfo/new.do', data : jsonuserinfo, dataType : 'json', success : function(resp) { if (resp.successed) { alert("数据已成功保存" ); //清除错误信息 elemUserinfo.applyErrors({}); } else { elemUserinfo.applyErrors(resp.errors); } }, error : failed }); };
其中的applyErrors是我自己写的一段函数,就是根据错误信息的元素名,给元素画个红框,然后
把错误信息写到该元素后面的<div class="errorMessage"></div>里。该函数的参数为空对象时
清除所有错误信息。代码如下:
/** * 突出显示错误的输入域,写错误信息 */ $.fn.applyErrors = function(es) { alert('applyErrors - ' + es); this.map(function() { $.each(this.elements, function() { var currElem = this; $(currElem).css('border-color', ''); //清除突出显示 $(currElem).nextAll('div').text(''); //清除错误信息 $.each(es, function() { if (this.element == currElem.name) { $(currElem).css('border-color', 'red'); //突出显示 $(currElem).nextAll('div').text(this.message); //错误信息 } }) }) }); };
我对javascript不太熟悉,这段代码是仿照serializeObject写的,哪位大侠有空,帮着改改,在下
不胜感激。
最后贴一张校验结果的图,我对美工不在行,画面比较丑,见笑了。
评论
18 楼
lym6520
2010-05-14
感觉很不错,呵,jquery都1.4.1了,楼主可以更新了,在性能上有了很大提高。
17 楼
bhzln
2010-05-12
这种校验不过是增加用户体验了,看起来效果好,实际上服务器端的提交校验不一样是不能省么,个人观点用个服务器端校验就行了,其他的都是等项目完成了有时间的时候装饰一下
16 楼
Angel_Night
2010-05-07
yiyu 写道
其实我一直觉得那些简单的数据合法性校验就在前台做就行了,后台只做业务合法性校验就行了,不知大家怎么看?
这东西 按情况划分 最合适
如果给一个公司做oa 那没有必要做太多的数据校验..
一个员工 是不会输入边界数据来玩极限的
最多做一些简单的前台验证就够了 当然 增加用户体验的ajax逻辑验证还是要有的..
如果是放在 天朝大局域网 上跑的东西
把验证做好...都不一定够..
15 楼
caoyangx
2010-05-07
呵呵,去年10月时,我同事也做了一个类似的,后台实体用验证注解,前台验证,效果很好,很方便。
14 楼
yiyu
2010-05-06
java_doc 写道
yiyu 写道
java_doc 写道
不错,但是在Chrome下不能用哦,还有在后台处理Json的请求和响应、验证也太繁琐了,为什么不像 Ajax Simplifications in Spring 3.0 那个sample那样处理呢?
chrome里不行啊?我看看,我一直在firefox里试的
我觉得Ajax Simplifications in Spring 3.0里有个问题,如果前台的数据转不成Account会怎么样?例如一个需要数字的地方输入了字符,我觉得会在开始校验前就出例外了,结果会是导致ajax通讯失败,而这不是我们想要的,我们想要的是ajax通讯正常结束,但是接收到的是校验错误信息
这确实是一个问题,在网上查了一下也有其他人遇到过,但是没有比较好的解决办法,简单的就是在客户端验证,这样就不会出现这种情况了,感觉这样也不是很好。
其实我一直觉得那些简单的数据合法性校验就在前台做就行了,后台只做业务合法性校验就行了,不知大家怎么看?
13 楼
java_doc
2010-05-06
yiyu 写道
java_doc 写道
不错,但是在Chrome下不能用哦,还有在后台处理Json的请求和响应、验证也太繁琐了,为什么不像 Ajax Simplifications in Spring 3.0 那个sample那样处理呢?
chrome里不行啊?我看看,我一直在firefox里试的
我觉得Ajax Simplifications in Spring 3.0里有个问题,如果前台的数据转不成Account会怎么样?例如一个需要数字的地方输入了字符,我觉得会在开始校验前就出例外了,结果会是导致ajax通讯失败,而这不是我们想要的,我们想要的是ajax通讯正常结束,但是接收到的是校验错误信息
这确实是一个问题,在网上查了一下也有其他人遇到过,但是没有比较好的解决办法,简单的就是在客户端验证,这样就不会出现这种情况了,感觉这样也不是很好。
12 楼
prowl
2010-05-06
Annotation的方式很新颖
11 楼
dmhorse
2010-05-06
我没用过json,但感觉老要创建 jsoncustomer之类的object有种代码重复的感觉.
10 楼
yiyu
2010-05-06
java_doc 写道
不错,但是在Chrome下不能用哦,还有在后台处理Json的请求和响应、验证也太繁琐了,为什么不像 Ajax Simplifications in Spring 3.0 那个sample那样处理呢?
chrome里不能执行的原因知道了,inputCustomerInfo.html里head里的style和script加载时好像给过滤掉了,把这两部分移到body里就行了。
不过感觉不太好,也许不该用这种页面加载的方式,哪位大侠有经验给出出主意吧
9 楼
yiyu
2010-05-06
java_doc 写道
不错,但是在Chrome下不能用哦,还有在后台处理Json的请求和响应、验证也太繁琐了,为什么不像 Ajax Simplifications in Spring 3.0 那个sample那样处理呢?
chrome里不行啊?我看看,我一直在firefox里试的
我觉得Ajax Simplifications in Spring 3.0里有个问题,如果前台的数据转不成Account会怎么样?例如一个需要数字的地方输入了字符,我觉得会在开始校验前就出例外了,结果会是导致ajax通讯失败,而这不是我们想要的,我们想要的是ajax通讯正常结束,但是接收到的是校验错误信息
8 楼
upup1000
2010-05-06
我发现java注解还是挺有用的,哈哈。
7 楼
java_doc
2010-05-06
不错,但是在Chrome下不能用哦,还有在后台处理Json的请求和响应、验证也太繁琐了,为什么不像 Ajax Simplifications in Spring 3.0 那个sample那样处理呢?
6 楼
hyl1234
2010-05-06
还没怎么看过spring3.0 下来看看效果 谢谢lz
5 楼
oakeye
2010-05-06
试试新的入例校验,之前都没作 只是在前端考虑了
4 楼
SSailYang
2010-05-06
在 Spring 出到 3.0.0 的时候,它内置的 Json 格式转换器还不支持 @DateTimeFormat 和 @NumberFormat,在 Ajax Simplifications in Spring 3.0 的这篇文章里作者自己写了一个 BeanPostProcessor 去解决这个问题。不知道 3.0.2 怎么样了
3 楼
godson_2003
2010-05-05
看起来感觉不错啊 明天好好研究研究
2 楼
yiyu
2010-05-05
对不起,代码在这里
1 楼
Angel_Night
2010-05-05
楼主又更新了啊
直接上源代码吧 跑上次那个demo 我花了1个小时...
直接上源代码吧 跑上次那个demo 我花了1个小时...
发表评论
-
log4j日志中输出sessionID的方法
2015-05-13 19:51 2425在web应用中,如果使用log4j做日志输出时,如果要输出s ... -
jdk输出带缩进格式xml的方法
2011-11-04 16:28 5461jdk自己带有xml处理的功能,好像是用的xerces和xal ... -
JasperReport与spring集成的三种方式
2011-08-10 14:38 16415最近要用JasperReport,试 ... -
jqGrid <-- json --> spring,hibernate之服务器端分页,排序
2011-06-07 16:22 7123最近做了一个以jqGrid实现的数据表格,与服务器端(spri ... -
在javax.servlet.Filter里设置Paramter
2011-02-17 16:04 1258今天碰到一个冷僻的需求,需要在Filter里增加request ... -
WebDav的java客户端开发包:Jackrabbit
2011-01-25 16:39 4773上一篇帖子“WebDav的java客户端开发包:sardine ... -
WebDav的java客户端开发包:sardine
2011-01-24 13:27 6462最近需要对WebDav服务器进行操作,查找了一下,基于java ... -
读取xml文件时不做validation的方法
2010-06-21 11:49 1656今天遇到一个问题,我使用dom4j读取一个xml文件的内容,该 ... -
jquery<--json-->spring(3.0)之DataTables的服务器端翻页
2010-05-15 10:45 5324本文是jquery<--json--> ... -
jquery(1.3.2)<--json-->spring(3.0)
2010-04-23 14:09 4100发现spring 3已经对ajax支持的很好了,前端可以只使用 ... -
使用HTML Parser获取需要HTTP认证的页面的方法
2010-04-09 13:48 1342HTML Parser(http://htmlparser.s ... -
使用javamail通过需要身份验证的smtp服务器发送邮件
2010-04-09 11:51 1736使用javamail发送邮件时,如果smtp服务器需要身份验证 ... -
Hibernate tools使用简介
2009-10-15 11:33 1504简单描述在Eclipse Java EE版中使用Hiberna ... -
关于ProcessBuilder执行dir命令报错
2009-05-15 10:09 2138今天无事,试一下ProcessBuilder,没想到这么一段简 ... -
YUI DataTable 服务器端翻页与排序
2009-01-23 14:45 3364这两天试用了一下YUI的DataTable,翻页和排序都在后台 ... -
使用json-lib的JSONObject.toBean( )时碰到的日期属性转换的问题
2009-01-22 16:21 2876今天碰到这样一个问题: 当前台以JSON格式向后台传递数据的 ... -
YUI + struts2实现基于JSON通讯的AJAX例子
2009-01-08 10:35 2434近来做了个小例子,前端使用YUI,后端使用struts2+sp ... -
Tiles与YUI LayoutManager的结合
2009-01-04 10:16 1558最近在学习YUI,深感功能全面,正在试探是否可以作为页面部分的 ...
相关推荐
在IT行业中,SSH、jQuery和JSON是三种非常重要的技术,它们在Web开发中扮演着关键的角色。本项目"ssh-jquery-json"是一个整合了这些技术的完整示例,旨在帮助开发者理解和应用它们。 首先,SSH是指Spring、Struts和...
,jQuery,jQuery-Easyui,JSON,JS技术,Maven技术,Ajax无刷新登录,注册等等,Mybatis技术,还有导出Excel通用方法,通用类有需要的朋友可以下下来直接使用,以及RestFUL风格增删改查,以及前端各种校验等等。...
标题 "S2SH+jQuery+JSON+Ajax注册--异步校验" 提及的技术栈主要包含四个关键部分:Struts2 (S2),Spring,Hibernate(SSH)这三大企业级开发框架,以及jQuery、JSON和Ajax这三者组成的前端交互技术。这篇博客文章...
<ul><li><a class="selected">1</a></li> <li><a href="search-cat-4-page-2.html" class="unselected">2</a></li> <li><a href="search-cat-4-page-3.html" class="unselected">3</a></li> <li><a href="search-cat...
<span id="usernameError"></span> <!-- 其他表单字段 --> <button type="submit">注册</button> </form> <script> $(document).ready(function() { $('#username').on('input', function() { var username = ...
注:此项目是用IntelliJ IDEA 13.1.3此软件编写而成,不过和myeclipse都差不多,本项目包含SpringMVC+JSON+mybatis+jQuery+Ajax+Maven做的无刷新登录,注册,修改密码,...以及校验并且赋有详细注释,以及增删改查功能
总结,"json使用的小包包"可能是关于如何在Spring MVC项目中有效利用JSON进行数据交换的实践案例或工具集合,涵盖了JSON的基本概念、Spring MVC中的JSON处理、数据验证以及与Ajax的结合使用等内容。通过学习和应用...
- `<action>`:每个Action都有一个对应的类实现业务逻辑。 - **Action配置**:Action是Struts2的核心组件之一,负责处理来自用户的请求。 - 返回结果:通过返回特定字符串来指示视图层如何响应。 - 输入参数:...
public ResponseEntity<UsernameCheckResponse> checkUsername(@RequestBody UsernameRequest request) { String username = request.getUsername(); boolean isUnique = userService.checkIfUsernameExists...
public ResponseEntity<PageModel> getPaginatedData(@RequestParam int page, @RequestParam int size) { Pageable pageable = PageRequest.of(page, size); Page<Data> dataPage = dataService.getData(pageable...
用户权限=所拥有角色权限合集+用户加权限-用户减权限,优先级:用户减权限>用户加权限>角色权限 > zheng-oss 文件存储系统,提供四种方案: - **阿里云** OSS - **腾讯云** COS - **七牛云** - 本地分布式存储 !...
SSH三大框架整合指的是Spring、Struts2和Hibernate这三个在Java Web开发中广泛应用的开源框架的集成。这三者结合在一起,可以构建出高效、模块化的Web应用程序。 **Spring框架** 是一个全面的后端开发框架,它提供...
注:此项目用IntelliJ IDEA 13.1.3编写,所用到的技术有springMVC注解,,jQuery,jQuery-Easyui,JSON,JS技术,Maven技术,Ajax无刷新登录,注册等等,并且赋有非常详细的注释,sql脚本。让你一看即明,在此项目中还...
- **常用标签**:列出并解释常用的Struts2标签,如<s:textfield>、<s:submit>等。 - **高级标签**:介绍一些高级标签的使用方法,如<s:iterator>用于循环遍历集合。 #### 九、表达式OGNL - **OGNL概述**:简述OGNL...
结合jQuery或其他JavaScript库,Spring MVC可以通过@ResponseStatus和@ResponseBody注解轻松实现Ajax请求的处理。 9. **RESTful API设计** Spring MVC 可以方便地构建RESTful风格的API,通过HTTP动词(GET、POST...
- **16.6 jQuery处理JSON**:jQuery处理JSON数据的方法。 #### 十七至十九章 - **实战案例**:通过具体的项目案例进一步加深对Struts2的理解,包括投票管理系统、无纸化办公管理系统、数据采集系统等。 以上内容...