05 JSF2-Validation and Converters

来源:互联网 发布:java equals的用法 编辑:程序博客网 时间:2024/05/22 15:25
一、Validation in the Action Controller:
1.Create error messages:
With null: store a message for the form as a whole
? context addMessage(null someFacesMessage);
– With component ID: store message specific to element
? context.addMessage("someID", someFacesMessage);
This assumes you used <h:form prependId="false">

FacesMessage message = new FacesMessage();
             message.setDetail("error details");
             message.setSummary("error summary");
             message.setSeverity(FacesMessage.SEVERITY_ERROR);


FacesContext context = FacesContext.getCurrentInstance();
    if (getUserID().equals("")) {
      context.addMessage(null,
          new FacesMessage("UserID required"));
    }
    if (getKeyword().equals("")) {
      context.addMessage(null,
          new FacesMessage("Keyword required"));
    }
    if (context.getMessageList().size() > 0) {
      return(null);//Returning null means to redisplay the form
    } else {
      doBusinessLogicForValidData();
      return("show-bid1");
    }

2.Display error messages:
<h:messages/>
<h:message for="userId"/>
<h:message showSummary="true" showDetail="false"
                   errorClass="error"
                   id="errors1" for="userNo"/>
二、Validation via Type Conversion:
<h:inputText value="#{bidBean2.keyword}"
required="true"
requiredMessage="You must enter a keyword"
converterMessage="Amount must be a number"
id="keyword"/></td>
<td><h:message for="keyword" styleClass="error"/>
三、Validation using the Validation using the JSF Validator Tags:
f:validateDoubleRange
f:validateLength
f:validateLongRange
f:validateBean
f:validateRegex
f:validateRequired
<h:inputText value="#{bidBean2.userID}"
             required="true"
             requiredMessage="You must enter a user ID"
             validatorMessage="ID must be 5 or 6 chars"
             id="userID">
      <f:validateLength minimum="5" maximum="6"/>
    </h:inputText>
    <h:message for="userID" styleClass="error"/>

当需要国际化时:

Message_zh_CN.properties:

例如:不能为空时:<h:inputText value="#{bidBean2.userID}"  required="true" />的错误提示:

javax.faces.component.UIInput.REQUIRED=不能为空
四、Validation using Validation using Custom Validator Methods:
<h:inputText value="#{bidBean2.bidAmount}"
required="true"
requiredMessage="You must enter an amount"
converterMessage="Amount must be a number"
validator="#{bidBean2.validateBidAmount}"
id="amount"/>

  public void validateBidAmount(FacesContext context,
                                UIComponent componentToValidate,
                                Object value)
      throws ValidatorException {
    double bidAmount = ((Double)value).doubleValue();
    double previousHighestBid = currentHighestBid();
    if (bidAmount <= previousHighestBid) {
      FacesMessage message =
        new FacesMessage("Bid must be higher than current " +
                         "highest bid ($" +
                         previousHighestBid + ").");
      throw new ValidatorException(message);
    }
五、Creating a custom validator(f:validator):
@FacesValidator(value = "ipValidator")
public class IpValidator implements Validator {
    private static final String IP_REGEX = "^([1-9]|[1-9][0-9]|1[0-
9][0-9]|2[0-4][0-9]|25[0-5])(\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-
4][0-9]|25[0-5])){3}$";
    public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
        String ipAddress = (String) value;
        Pattern mask = null;
        mask = Pattern.compile(IP_REGEX);
        Matcher matcher = mask.matcher(ipAddress);
        if (!matcher.matches()) {
            FacesMessage message = new FacesMessage();
            message.setDetail("IP not valid");
            message.setSummary("IP not valid");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(message);
        }
    }
}

<h:inputText id="ipID" required="true" value="#{ipBean.ipValue}">
     <f:validator validatorId="ipValidator"/>
</h:inputText>

六、bean validation:
作为Java EE 6规范的一部分,JSR 303 - bean validation, 提供了一个独立于应用程序层的定义数据验证约束的机制。这个JSR允许我们通过annotation来指定数据验证约束。当没有使用Java EE 6服务器的时候,我们也可以使用Hibernate Validator(JSR 303的另外一个实现)。
Annotation施加的约束@NotNullCannot be null@MinMust be a number and whose value must higher or equal to the specified number.@MaxMust be a number and whose value must lower or equal to the specified number.@SizeMust be between specified minimum and maximum limits@PatternMust match the specified Java regular expressionValidationMessages.properties:
javax.validation.constraints.Size.message=size must be betweenss {min} and {max}
javax.validation.constraints.Size为@Size的全路径
ValidationMessages_zh_CN.properties:
javax.validation.constraints.Size.message=必须在{min}与{max}之间
org.hibernate.validator.constraints.NotEmpty.message=不能为空
验证:
@NotNull
    @Size(min = 1, message = "{validator.notEmpty}")
    public String getEmailAddress() {
        return emailAddress;
    }
页面验证:
<h:inputText id="age" value="#{myBean.age}">
   <f:validateBean disabled="true" />
</h:inputText>
自定义验证:
Email.java:
@Documented
@Constraint(validatedBy = EmailConstraintValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Email {
    // message string should be {constraint.email}

    String message() default "{validator.email}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
EmailConstraintValidator.java:
public class EmailConstraintValidator
      implements ConstraintValidator<Email, String> {

    private Pattern pattern;

    public void initialize(Email parameters) {
        // credit goes to http://www.regular-expressions.info/email.html
        pattern = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$",
                                  Pattern.CASE_INSENSITIVE);
    }

    public boolean isValid(String value, ConstraintValidatorContext ctxt) {
        if (value == null || value.length() == 0) {
            return true;
        }

        return pattern.matcher(value).matches();
    }

}
使用:
@Email
public String getEmailAddress() {
    return emailAddress;
}
3.群组:
JSF 2.0还提供了<f:validateBean>标签,这个标签允许我们使用validation组。一个validation组定义了约束条件的一个子集,每个约束条件可以属于一个或多个组。我们可以在验证组件的时候使用validateiongGroups属性指定要验证的组。代码如下:
  1. <h:inputText value="#{bean.prop1}">

  2. <f:validateBean validationGroups="com.demo.validation.groups.Group1"/>
  3. </h:inputText>

我们可以使用如下的代码来定义一个组,如:
  1. package com.demo.validation.groups;
  2. public interface Group1{
  3. }

你没有看错,就是一个空的接口。
一个组可以扩展另外一个组,如
  1. package com.demo.validation.groups;
  2. public interface Group2 extends Group1{
  3. }

每个约束条件的annotation都有一个Group属性,我们可以通过该属性来指定这个约束条件属于那个组。如
@Size(min = 1, message = "Please enter the Email",groups=Group1.class)
如果没有指定groups,缺省的所有的约束都属于javax.validation.groups.Default组。这个组是一个内建的接口。
七、Customizing error messages for validators:
1.default messages from Message.propertie;
2.Even if we are in JSF 2.0, we need to configure this properties file in faces-config.xml.
This can be done as follows:
3.custom error messages:
<application>
  <locale-config>
    <default-locale>en</default-locale>
  </locale-config>
  <message-bundle>users.MyMessages</message-bundle>
</application>
页面中:
<f:loadBundle basename="Messages" var="msg"/>
八、Binding validators to backing bean properties:
<h:inputText id="ageID" required="true"
               value="#{userBean.userAge}">
    <f:validateLongRange binding="#{userBean.longAge}"/>
  </h:inputText>

private LongRangeValidator longAge;
public LongRangeValidator getLongAge(){
    return this.longAge;
  }
  public void setLongAge(LongRangeValidator longAge){
    longAge.setMinimum(18);
    longAge.setMaximum(90);

    this.longAge=longAge;
  }

九、转换器:
f:convertDateTime
<h:body>
      <b><h:outputText value="-Formatting the current date
                                               and time-"/></b><br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime type="date" dateStyle="medium"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime type="date" dateStyle="full"/>
</h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime type="time" timeStyle="full"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime type="date" pattern="dd/mm/yyyy"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime dateStyle="full" pattern="yyyy-mm-dd"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime dateStyle="full"
                          pattern="yyyy.MM.dd 'at' HH:mm:ss z"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime dateStyle="full" pattern="h:mm a"/>
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime dateStyle="long"
                          timeZone="EST" type="both" />
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime locale="ro"
                          timeStyle="long" type="both"
                          dateStyle="full" />
      </h:outputText>
      <br />
      <h:outputText value="#{datetimeBean.currentdate}">
        <f:convertDateTime locale="de"
                          timeStyle="short" type="both"
                          dateStyle="full" />
      </h:outputText>
    </h:body>
f:convertNumber
<h:body>
  <b><h:outputText value="-Formatting the double 
                                      value 12345.12345-"/></b><br />
        <!-- Format as 00000.00000 -->
        <h:outputText value="Format as 00000.00000: "/>
        <h:outputText value="#{numbersBean.doubleNumber}">
            <f:convertNumber type="number" maxIntegerDigits="5"
                             maxFractionDigits="5"
                             groupingUsed="false"/>
        </h:outputText>
        <br />
        <!-- Format as 00000 -->
        <h:outputText value="Format as 00000: "/>
        <h:outputText value="#{numbersBean.doubleNumber}">
            <f:convertNumber type="number" maxIntegerDigits="5"
                             maxFractionDigits="0"/>
        </h:outputText>
        <br />
      <!-- Format as currency -->
        <h:outputText value="Format as currency: "/>
        <h:outputText value="#{numbersBean.doubleNumber}">
            <f:convertNumber type="currency" currencySymbol="$"
                             maxIntegerDigits="5"
                             maxFractionDigits="2"/>
        </h:outputText>
        <br />
        <!-- Format as percent -->
        <h:outputText value="Format as percent: "/>
        <h:outputText value="#{numbersBean.doubleNumber}">
            <f:convertNumber type="percent" maxIntegerDigits="5"
                             maxFractionDigits="5"/>
        </h:outputText>
        <br />
        <!-- Format as pattern #####,00% -->
        <h:outputText value="Format as pattern #####,00%: "/>
        <h:outputText value="#{numbersBean.doubleNumber}">
             <f:convertNumber pattern="#####,00%"/>
        </h:outputText>
    </h:body>
Creating and using a custom converter
@FacesConverter(value = "customDateConverterImpl")
public class CustomDateConverterImpl implements Converter {
    public String getAsString(FacesContext arg0, UIComponent arg1,
Object arg2) {
        if (arg0 == null) {
            throw new NullPointerException("context");
        }
        if (arg1 == null) {
            throw new NullPointerException("component");
        }
        final Date date = (Date) arg2;
        String DATE_FORMAT = "yyyy-MM-dd";
        SimpleDateFormat sdf =
                new SimpleDateFormat(DATE_FORMAT);
        Calendar c1 = Calendar.getInstance(); // today
        c1.setTime(date);
        return sdf.format(c1.getTime());
    }
    public Object getAsObject(FacesContext arg0, UIComponent arg1,
String arg2) {
        if (arg0 == null) {
            throw new NullPointerException("context");
        }
        if (arg1 == null) {
            throw new NullPointerException("component");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date today = df.parse(arg2);
            return today;
        } catch (ParseException e) {
            FacesMessage message = new FacesMessage(FacesMessage.
SEVERITY_ERROR,
                    "Parser error!", "Cannot parse this date!");
            throw new ConverterException(message);
        }
    }
}

<h:form id="customDateTimeID">
 <h:inputText id="dateID" value="#{datetimeBean.currentdate}"
              converter="customDateConverterImpl">
 </h:inputText>
 <h:message showSummary="true" showDetail="false" for="dateID"
            style="color: red; text-decoration:overline"/>
 <br />
 <h:commandButton value="Submit"
                  action="selected?faces-redirect=true"/>
</h:form>
其中:@FacesConverter(value = "customDateConverterImpl")也可以在 faces-config.xml中配置
<converter>
  <converter-id>CONVERTER_ID</converter-id>
  <converter-class>CONVERTER_CLASS_NAME</converter-class>   
</converter>

扩充某个转换器:
@FacesConverter(value = "customDateConverterExtend")
public class CustomDateConverterExtend extends DateTimeConverter {
  public CustomDateConverterExtend() {
    super();
    setTimeZone(TimeZone.getDefault());
    setPattern("yyyy-MM-dd");
  }
}
Binding converters to backing bean  properties:
<h:form id="numberFormID">
  <h:inputText id="numberID" value="#{numbersBean.numbery}">
    <f:convertNumber binding="#{numbersBean.number}" />
  </h:inputText>
  <h:message showSummary="true" showDetail="false" for="numberID"
             style="color: red; text-decoration:overline"/>
  <br />
  <h:commandButton value="Submit"
                   action="selected?faces-redirect=true"/>
</h:form>

private NumberConverter number;
public NumberConverter getNumber(){
    return this.number;
 }
public void setNumber(NumberConverter number){
    number.setType("currency");
    number.setCurrencySymbol("$");
    this.number=number;
 }

f:converter
<!-- explicit conversion using the UIComponent converter attribute -->
<h:inputText id="userAgeID" required="true"
             value="#{userBean.userAge}"
             converter="javax.faces.Integer">
</h:inputText>
<!-- converter tag nested within a UIComponent -->
<h:inputText id="userAgeID" required="true"
             value="#{userBean.userAge}">
  <f:converter converterId="javax.faces.Integer"/>
</h:inputText>

0 0
原创粉丝点击