WEB开发网      婵犵數濮烽弫鍛婄箾閳ь剚绻涙担鍐叉搐绾剧懓鈹戦悩瀹犲闁汇倗鍋撻妵鍕箛閸洘顎嶉梺绋款儑閸犳劙濡甸崟顖氬唨闁靛ě浣插亾閹烘鈷掗柛鏇ㄥ亜椤忣參鏌″畝瀣暠閾伙絽銆掑鐓庣仭缁楁垿姊绘担绛嬪殭婵﹫绠撻、姘愁樄婵犫偓娴g硶鏀介柣妯款嚋瀹搞儱螖閻樺弶鍟炵紒鍌氱Ч瀹曟粏顦寸痪鎯с偢瀵爼宕煎☉妯侯瀳缂備焦顨嗗畝鎼佸蓟閻旈鏆嬮柣妤€鐗嗗▓妤呮⒑鐠団€虫灀闁哄懐濮撮悾鐤亹閹烘繃鏅濋梺闈涚墕濡瑩顢欒箛鏃傜瘈闁汇垽娼ф禒锕傛煕閵娿儳鍩f鐐村姍楠炴﹢顢欓懖鈺嬬幢闂備浇顫夊畷妯肩矓椤旇¥浜归柟鐑樻尭娴滃綊姊虹紒妯虹仸闁挎洍鏅涜灋闁告洦鍨遍埛鎴︽煙閼测晛浠滃┑鈥炽偢閹鈽夐幒鎾寸彇缂備緡鍠栭鍛搭敇閸忕厧绶炴俊顖滅帛濞呭洭姊绘担鐟邦嚋缂佽鍊垮缁樼節閸ャ劍娅囬梺绋挎湰缁嬫捇宕㈤悽鍛婄厽閹兼番鍨婚埊鏇㈡煥濮樿埖鐓熼煫鍥ュ劤缁嬭崵绱掔紒妯肩畺缂佺粯绻堝畷姗€濡歌缁辨繈姊绘担绛嬪殐闁搞劋鍗冲畷顖炲级閹寸姵娈鹃梺缁樻⒒閳峰牓寮崒鐐寸厱闁抽敮鍋撻柡鍛懅濡叉劕螣鐞涒剝鏂€闂佺粯鍔曞Ο濠囧吹閻斿皝鏀芥い鏃囨閸斻倝鎽堕悙鐑樼厱闁哄洢鍔屾晶顖炴煕濞嗗繒绠婚柡灞界Ч瀹曨偊宕熼鈧▍锝囩磽娴f彃浜炬繝銏f硾椤戝洨绮绘ィ鍐╃厵閻庢稒岣跨粻姗€鏌ㄥ☉妯夹fい銊e劦閹瑩顢旈崟顓濈礄闂備浇顕栭崰鏍礊婵犲倻鏆﹂柟顖炲亰濡茶鈹戦埄鍐ㄧ祷妞ゎ厾鍏樺璇测槈閵忕姈鈺呮煏婢跺牆鍔撮柛鏂款槺缁辨挻鎷呯粙搴撳亾閸濄儳鐭撶憸鐗堝笒閺嬩線鏌熼崜褏甯涢柡鍛倐閺屻劑鎮ら崒娑橆伓 ---闂傚倸鍊搁崐鐑芥倿閿旈敮鍋撶粭娑樺幘濞差亜鐓涢柛娑卞幘椤斿棝姊虹捄銊ユ珢闁瑰嚖鎷�
开发学院软件开发Java JSR 303 - Bean Validation 介绍及最佳实践 阅读

JSR 303 - Bean Validation 介绍及最佳实践

 2012-03-20 15:32:26 来源:WEB开发网 闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷闂傚倸鍊搁崐椋庣矆娓氣偓楠炲鏁撻悩鎻掔€梺姹囧灩閻忔艾鐣烽弻銉︾厵闁规鍠栭。濂告煕鎼达紕校闁靛洤瀚伴獮鎺楀箣濠靛啫浜鹃柣銏⑶圭壕濠氭煙閻愵剚鐏辨俊鎻掔墛缁绘盯宕卞Δ鍐冣剝绻涘畝濠佺敖缂佽鲸鎹囧畷鎺戭潩閹典焦鐎搁梻浣烘嚀閸ゆ牠骞忛敓锟�婵犵數濮烽弫鍛婃叏椤撱垹绠柛鎰靛枛瀹告繃銇勯幘瀵哥畼闁硅娲熷缁樼瑹閳ь剙岣胯鐓ら柕鍫濇偪濞差亜惟闁宠桨鑳堕崝锕€顪冮妶鍡楃瑐闁煎啿鐖奸崺濠囧即閵忥紕鍘梺鎼炲劗閺呮稒绂掕缁辨帗娼忛埡浣锋闂佽桨鐒﹂幑鍥极閹剧粯鏅搁柨鐕傛嫹闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷  闂傚倸鍊搁崐鐑芥嚄閼哥數浠氱紓鍌欒兌缁垶銆冮崨鏉戠厺鐎广儱顦崡鎶芥煏韫囨洖校闁诲寒鍓熷铏圭磼濡搫顫岄梺鍦拡閸嬪棝鎯€椤忓浂妯勯梺鍝勬湰濞叉ḿ鎹㈠┑濠勭杸闁哄洨濮烽悰銉╂⒒娴e搫甯跺鐟帮攻缁傚秴饪伴崼姘e亾閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡涱€楀褜鍠栭湁闁绘ɑ鐟ョ€氼喚绮绘ィ鍐╃厱妞ゆ劑鍊曢弸搴ㄦ煟韫囧鍔滈柕鍥у瀵潙螣閸濆嫬袝婵$偑鍊戦崹娲偡閳哄懎绠栭柍鈺佸暞閸庣喖鏌曢崶褍绨婚柟鍑ゆ嫹
核心提示: public class Product { // 必须非空 @NotEmpty private String productName; // 必须在 8000 至 10000 的范围内 // @Price 是一个定制化的 constraint @Price private float price;
public class Product { // 必须非空 @NotEmpty private String productName; // 必须在 8000 至 10000 的范围内 // @Price 是一个定制化的 constraint @Price private float price; … Getter 和 setter }


清单 3. OrderQuery.java

// 'to'所表示的日期必须在'from'所表示的日期之后 // @QueryConstraint 是一个定制化的 constraint @QueryConstraint public class OrderQuery { private Date from; private Date to; … omitted … Getter and setter }

定制化的 constraint

@Price是一个定制化的 constraint,由两个内置的 constraint 组合而成。


清单 4. @Price 的 annotation 部分
 

// @Max 和 @Min 都是内置的 constraint @Max(10000) @Min(8000) @Constraint(validatedBy = {}) @Documented @Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface Price { String message() default "错误的价格"; Class[] groups() default {}; Class[] payload() default {}; }

@Status是一个新开发的 constraint.


清单 5. @Status 的 annotation 部分
 

@Constraint(validatedBy = {StatusValidator.class}) @Documented @Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface Status { String message() default "不正确的状态 , 应该是 'created', 'paid', shipped', closed'其中之一"; Class[] groups() default {}; Class[] payload() default {}; }


清单 6. @Status 的 constraint validator 部分

public class StatusValidator implements ConstraintValidator{ private final String[] ALL_STATUS = {"created", "paid", "shipped", "closed"}; public void initialize(Status status) { } public boolean isValid(String value, ConstraintValidatorContext context) { if(Arrays.asList(ALL_STATUS).contains(value)) return true; return false; } }

Bean Validation API 使用示例

创建订单

用户在创建一条订单记录时,需要填写以下信息:订单编号,客户,电子信箱,地址,状态,产品名称,产品价格


图 3. 创建订单

 

对这些信息的校验,使用 Bean Validation API


清单 7. 代码片段
 

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); // 从 request 中获取输入信息 String orderId = (String) req.getParameter("orderId"); String customer = (String) req.getParameter("customer"); String email = (String) req.getParameter("email"); String address = (String) req.getParameter("address"); String status = (String) req.getParameter("status"); String productName = (String) req.getParameter("productName"); String productPrice = (String) req.getParameter("productPrice"); // 将 Bean 放入 session 中 Order order = new Order(); order.setOrderId(orderId); order.setCustomer(customer); order.setEmail(email); order.setAddress(address); order.setStatus(status); order.setCreateDate(new Date()); Product product = new Product(); product.setName(productName); if(productPrice != null && productPrice.length() > 0) product.setPrice(Float.valueOf(productPrice)); order.setProduct(product); session.setAttribute("order", order); ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set> violations = validator.validate(order); if(violations.size() == 0) { session.setAttribute("order", null); session.setAttribute("errorMsg", null); resp.sendRedirect("creatSuccessful.jsp"); } else { StringBuffer buf = new StringBuffer(); ResourceBundle bundle = ResourceBundle.getBundle("messages"); for(ConstraintViolation violation: violations) { buf.append("-" + bundle.getString(violation.getPropertyPath().toString())); buf.append(violation.getMessage() + " n"); } session.setAttribute("errorMsg", buf.toString()); resp.sendRedirect("createOrder.jsp"); } }

如果用户不填写任何信息提交订单,相应的错误信息将会显示在页面上


图 4. 验证后返回错误信息

 

其实在整个程序的任何地方都可以调用 JSR 303 API 去对数据进行校验,然后将校验后的结果返回。


清单 8. 调用 JSR 303 API 进行校验
 

Order order = new Order(); … ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set> violations = validator.validate(order);

 

结束语

JSR 303 的发布使得在数据自动绑定和验证变得简单,使开发人员在定义数据模型时不必考虑实现框架的限制。当然 Bean Validation 还只是提供了一些最基本的 constraint,在实际的开发过程中,用户可以根据自己的需要组合或开发出更加复杂的 constraint

 

上一页  1 2 

Tags:JSR Bean Validation

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接