JEE6/JSF2.0 error messages, bean validation and i18n

11 篇文章 0 订阅
10 篇文章 0 订阅

With JEE6/JSF2.0, validation can be done by bean validation annotations. these annotations can be put on the JEE6 entity beans OR managed backing beans, as long as they conform to the Java Bean requirement, ie, providing getter and setter methods for instance variables.

 

Bean validation messages are i18n ready. To internationalize the validation messages, you need to provide the localized messages in a properties file "ValidationMessages.properties" and put it under the applications class path. For web applications, this would be "WEB-INF/classes". This is similar to JSF's i18n solution. But you don't need to configure it in "web.xml" or "faces-config.xml", since it's bean validation framework available to you automatically.

 

For example, if you want to support both English and Chinese for your bean validation, you can provide the messages in two files and put them under "WEB-INF/classes":

 

WEB-INF/classes/ValidationMessages.properties

WEB-INF/classes/ValidationMessages_zh.properties

 

Following is an example of ValidationMessages.properties :

bean.validate.username.required=username is required to login
bean.validate.nameFilter.required=name filter is required to search!
bean.validate.nameFilter.short=name filter too short, at least 3 chars

 

And the corresponding message for Chinese support from ValidationMessages_zh.properties :

bean.validate.username.required=\u7528\u6237\u540D\u662F\u5FC5\u987B\u5730\uFF01
bean.validate.nameFilter.required=\u540D\u5B57\u662F\u5FC5\u987B\u5730\uFF0C\u5A9A\u7EB8\uFF01
bean.validate.nameFilter.short=\u540D\u5B57\u592A\u77ED\u4E86\uFF0C\u81F3\u5C11 3 \u4E2A\u5B57\u7B26

 

Here's an exmple for JEE entity bean:

package com.jxee.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

/**
 * entity bean to table "test.user"
 * validation done here as well -- this is excellent!
 */
@Entity
@Table(name="USER", uniqueConstraints = @UniqueConstraint(columnNames = "username"))
public class User implements Serializable {
  
  @Id
  @GeneratedValue
  @Column(name="id")
  private Integer userid;
  
  @Column(name="username")
  // NotNull validation message are localized and defined in
  // ValidationMessages.properties/ValidationMessages_zh.properties
  @NotNull(message="{bean.validate.username.required}")
  // Size validation message is hard-coded here:
  @Size(min=4,max=20,message="username must be 4-20 characters")
  private String username;

  // other instance variables, getters and setters...

}

 

 

The following code illustrates how to use it in you bean class (the managed student search bean):

 

package com.jxee.action.student;

import java.io.Serializable;
import java.util.List;
import java.util.TimeZone;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.inject.Inject;

// bean validation annotations
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.log4j.Logger;

import com.jxee.ejb.student.StudentDAO;
import com.jxee.model.student.Student;

@ManagedBean(name="ss")
@ViewScoped
public class StudentSearchUseFlash implements Serializable {

  private static final Logger log = Logger.getLogger(StudentSearchUseFlash.class);
  private static final String SEARCH_PAGE = "/student/studentSearch.xhtml";
  
  private List<Student> searchResultList;
  private @EJB StudentDAO dao;

  // use bean validation to validate the search filter
  @NotNull(message="{bean.validate.nameFilter.required}")
  @Size(min=3, message="{bean.validate.nameFilter.short}")
  private String nameFilter;

  private int maxRows = 50;

  ......

} 

 

 

To display the localized bean validation message, you use <h:messages/>, <h:message for="inputId"/>, or Primefaces tags <p:messages/> and <p:message for="inputId"/>. This is standard JSF2.0 stuff, as illustrated here:

 

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   				xmlns:h="http://java.sun.com/jsf/html"
      			xmlns:f="http://java.sun.com/jsf/core"
      			xmlns:ui="http://java.sun.com/jsf/facelets"
      			xmlns:p="http://primefaces.org/ui"
   				template="/template/template1.xhtml">
   				
	<ui:define name="title">#{msgs.studentSearch}</ui:define>
    
	<ui:define name="content">
		<h:form id="searchForm">
		    <p:panel header="#{msgs.studentSearch}" style="width:60%">
	        <h:panelGrid columns="4">
	            <h:outputLabel value="#{msgs.name}: "/>
	            <h:inputText id="nf" value="#{ss.nameFilter}"/>
	            <p:message for="nf"/>
	            <h:commandButton type="submit" value="#{msgs.search}" 
                                     action="#{ss.findByName}"/>
	        </h:panelGrid>
		    </p:panel>
		</h:form>
		    	
		......

         </ui:define>
</ui:composition>

 

Here's the screen shot for the student search screen, where it requires the name filter to be at 3 characters long:


 

We can see that bean validation framework and JSF2 can work together pretty well.

 

One last thing to mention is how to localize a FacesMessage in my program? That is, how to access the i18n messages in backing beans? Since the i18n messages are handled as resource bundles, you need to reference it by the ResourceBundle class:

 

FacesContext cntxt = FacesContext.getCurrentInstance();
Locale locale = cntxt.getViewRoot().getLocale();
// load the i18n messages as resource bundle to access
// note: the base name must match the file path, ie, "/com/jxee/messages.properties"
ResourceBundle messages = ResourceBundle.getBundle("com.jxee.messages", locale);
String msg = messages.getString("nameFilterRequired");
log.debug("error message: " + msg);
cntxt.addMessage(null, new FacesMessage(msg));
 

 

This might be useful when it comes to cross-field validations. For single field vaidation, bean validation is handy and clean, thus much easier to use.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值