Trong bài viết này, tôi sẽ hướng dẫn các bạn cách để Validation trong Spring MVC. Một trong những yếu tố phổ biến nhất của ứng dụng web là xác nhận dữ liệu từ người dùng. Bất cứ khi nào người dùng gửi dữ liệu vào hệ thống của bạn, thì dữ liệu đó phải cần được xác nhận.
Lý do vì sao chúng ta cần Validation cho form?
Đơn giản, mục đích chính ở đây là là để ngăn chặn các cuộc tấn công, dữ liệu xấu, và lỗi của người dùng. Một số trường hợp chúng ta cũng có thể dùng jquery validation để valid cho form, tuy nhiên người dùng có thể tắt javascript và lúc này đương nhiên là việc validation không còn tác dụng.Các bạn có thể xem bài viết validation với jquery tại đây. Cho nên việc chúng ta cần phải validation không chỉ với trình duyệt mà còn phải validation ở phía Server. Ở đây tôi đang nói đến việc chúng ta cần valid với Spring MVC.
Hướng dẫn này sẽ hướng dẫn,giải thích cơ bản về validation với Spring MVC.
Điều kiện tiên quyết:
Bạn cần phải có một sự hiểu biết cơ bản về cách sử dụng, luồng đi của ứng dụng Spring MVC. Nếu bạn chưa hiểu các khái niệm cơ bản của Spring MVC, hãy làm theo một số hướng dẫn về Spring của tôi trước khi thực hiện bài này.
Hãy bắt đầu nào. Để bắt đầu, trước tiên chúng ta cần có một số thư viện cần có để sử dụng Hibernate Validator :
- hibernate-validator-5.4.1.Final.jar
- hibernate-validator-annotation-processor-5.4.1.Final.jar
- hibernate-validator-cdi-5.4.1.Final.jar
required:
Để đãm bảo cho việc uỷ thác các yêu cầu điều khiển trong ứng dụng Sprung của bạn, chúng ta thêm vào thẻ:
annotation-driven. Các bạn có thể tìm hiểu kỹ hơn ở bài viết này. Click.
Tất nhiên chúng ta sẽ có các thư viện cần thiết để có thể chạy một ứng dụng Spring MVC.
Java Configuration:
@Configuration @EnableWebMVC // this does the trick @ComponentScan(basePackages="com.codetutr") public class WebConfig { // beans here }
XML Configuration:
<mvc:annotation-driven />
Bay giờ , chúng ta có một đối tượng (Object) Subscriber cần valid như sau:
package entities;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
public class Subscriber {
@Size(min = 2, max = 30)
private String name;
@NotEmpty
@Email
private String email;
@NotNull
@Min(13)
@Max(110)
private Integer age;
@Size(min = 10)
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Tiếp theo chúng ta cần thực hiện việc xử lý và kiểm tra tại controller:
FormController.java
package controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import entities.Subscriber;
@Controller
public class FormController {
@RequestMapping(value="form", method=RequestMethod.POST)
public String submitForm(@Valid Subscriber subscriber, BindingResult result) {
if(result.hasErrors()) {
return "form";
}
return "form";
}
@RequestMapping(value="form", method=RequestMethod.GET)
public String submitForm() {
return "form";
}
}
Đơn giản chỉ cần thêm @ Valid trước đối tượng cần kiểm tra để cho Spring xác nhận đối tượng “Subscriber“. Lưu ý rằng chúng ta cũng thêm một đối số “BindingResult”. Đây là đối tượng của Spring giữ kết quả của việc xác nhận và ràng buộc và chứa các lỗi có thể đã xảy ra. Các BindingResult phải để ngay sau khi đối tượng được xác nhận tức là đặt ngay @ModelAttribute nếu không Spring sẽ không xác nhận đối tượng và ném một ngoại lệ.
Khi Spring thấy “@Valid”, nó cố gắng tìm kiểm chứng cho đối tượng đang được xác nhận. Spring tự động chọn các chú thích xác nhận nếu bạn đã kích hoạt “annotation-driven”. Spring sau đó gọi trình xác nhận và đặt bất kỳ lỗi nào trong BindingResult.
Tiếp theo, chúng ta sẽ tạo một view như sau:
Tạo file form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Form Đăng ký</title>
</head>
<body>
<h3>Form Đăng ký</h3>
<form action="${pageContext.request.contextPath }/form" method="post">
Name: <input type="text" name="name" value="" /><br /><br />
<form:errors path="objItem.name" cssStyle="color:red;display:block"></form:errors>
Email: <input type="text" name="email" value="" /><br /><br />
<form:errors path="objItem.email" cssStyle="color:red;display:block"></form:errors>
Age : <input type="text" name="age" value="" /><br /><br />
<form:errors path="objItem.age" cssStyle="color:red;display:block"></form:errors>
Phone : <input type="text" name="phone" value="" /><br /><br />
<form:errors path="objItem.phone" cssStyle="color:red;display:block"></form:errors>
<input type="submit" name="submit" value="Đăng ký" /><br /><br />
</form>
</body>
</html>
Ở đây chúng ta sử dụng thẻ “form: errors” để xuất hiện thông báo lỗi đến đường dẫn được chỉ định là path.
Ok! Bay giờ chúng ta cùng chạy ứng dụng Spring MVC:
Khi các bạn nhấn nút đăng ký, chúng ta đã valid được khi người dùng nhập không đúng theo yêu cầu. Tuy nhiên thông báo lỗi có vẻ hơi tệ ^^. Vấn đề ở đây tôi muốn thông báo ra để người dùng trải nghiệm tốt hơn thì các bạn có thể làm như sau:
@NotEmpty(message="Email không được rỗng!") @Email(message="Email không nhập đúng định dạng")
Điều này thật sự tốt khi chúng ta chạy lại ứng dụng, nó hiển thị được tiếng việt.
Tuy nhiên với khi valid như thế này thì nó không hỗ trợ quốc tế hóa (not support internationalization). Nghĩa là một số Annoation không hiển thị được tiếng việt như mong muốn. Ví dụ như trường Age, chúng ta muốn hiển thị theo thông báo của chúng ta.Lúc này, các bạn có thể dễ dàng ghi đè lên các tin nhắn mặc định . Để thực hiện việc này, trước tiên hãy thiết lập message bundle:
JavaConfig:
@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; }
XML Config:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages"/> </bean>
Bây giờ, tạo một file có tên “messages.properties” trong thư mục “WEB-INF/classes“. Chúng ta có thể ghi đè lên các thông báo lỗi mặc định. Thông báo lỗi được giải quyết bằng cách sử dụng mẫu sau:
- @NotNull thì hiển thị thông báo : Bạn nhập vào trường này!
- @Min(13) thì hiển thị thông báo : Bạn nhập vào tuổi ít nhất là 13.
- @Max(110) thì hiển thị thông báo : Bạn nhập vào tuổi lớn nhất nhất là 110.
Cách thông báo trong file messages.properties như sau:
NotNull.objItem.age=Tuoi khong duoc de trong Min.objItem.age=Nhap tuoi it nhat la 13 Max.objItem.age=Nhap tuoi it nhat la 110 typeMismatch=Nhap vao mot so
Những trường khác, các bạn muốn ghì đè nội dung tin nhắn thì làm tương tự.
Khi chạy ứng dụng chúng ta đã hiển thị thông báo như mong muốn :
#Tổng kết
OK. Vậy là chúng ta đã thực hiện validation đươọc dữ liệu khi người dùng nhập vào form trước khi thực thi đăng ký người dùng. Hãy luôn ghi nhớ rằng “đừng bao giờ tin vào dữ liệu người dùng nhập vào“, vì thế luôn validate dữ liệu trước khi lưu vào hệ thống nhé.
Chúc các bạn thực hiện thành công!