Structs2 输入校验,Action中校验,在xml中校验


这里写图片描述


输入校验

在Structs2中,我们可以实现对action的所有方法进行校验或者对action的指定方法进行校验。

校验示例1-在action中验证

这里写图片描述

对一个form表单进行数据校验,运用action中的validate 方法判断,是否为空,通过<s:fielderror/>进行提示,涉及input的处理结果类型,接收form表单的数据则用ModelDriver,动态方法调用则是用通配符的方式
执行结果:

这里写图片描述

<s:fielderror/> 显示错误信息,通过this.addFieldError("username", "用户名不能为空");的格式添加错误信息,类似一个list集合

姓名下方的<s:fielderror fieldName="username"/>只会显示姓名栏的校验信息

update方法不会进行校验

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:fielderror ></s:fielderror>
    <form action="user_login.action" method="post">
    姓名:<input type="text" name="username"/><s:fielderror fieldName="username"></s:fielderror><br/>
    密码:<input type="password" name="password"/><br/>
    mobile:<input type="text" name="mobile"/><br/>
    <input type="submit"value="登录">

    </form>
    <a href="user_update.action">update</a>
</body>
</html>

User.java

//package model;
/**
 * Title: User
 * Description: 对应form表单的数据实体类
 * @author Peng
 * @date 下午6:34:50
 */
public class User {
    private String username;
    private String password;
    private String mobile;

    //getter and setter
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + ", mobile=" + mobile + "]";
    }   
}

UserAction.java

//package action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import model.User;

@SuppressWarnings("serial")
public class UserAction extends ActionSupport implements ModelDriven<User>{

    private User user = new User();//这里需要实例化

    public String login(){
        System.out.println(user.toString());
        System.out.println("执行了login");
        return SUCCESS;
    }
    public String update(){

        System.out.println("执行了update");
        return "update";
    }

    /*//全部方法执行前,都会执行此验证方法
    @Override
    public void validate() {
        if(user.getUsername()==null||"".equals(user.getUsername())){
            this.addFieldError("username", "用户名不能为空");
        }
        if(user.getPassword()==null||"".equals(user.getPassword())){
            this.addFieldError("password", "密码不能为空");
        }
        if(user.getMobile()==null||"".equals(user.getMobile())){
            this.addFieldError("mobile", "手机号不能为空");
        }
    }*/

    //只做login()方法的验证
    public void validateLogin() {
        if(user.getUsername()==null||"".equals(user.getUsername())){
            this.addFieldError("username", "用户名不能为空");
        }
        if(user.getPassword()==null||"".equals(user.getPassword())){
            this.addFieldError("password", "密码不能为空");
        }
        if(user.getMobile()==null||"".equals(user.getMobile())){
            this.addFieldError("mobile", "手机号不能为空");
        }
    }
    @Override
    public User getModel() {

        return user;
    }
}

如果用注释的 validate() 方法,则会对所有的 action 中的方法进行校验,包括 update 方法,如果错误,会返回 input 处理结果类型。
如果只想对 action 中某个特定的方法进行校验,则可以使用 validate+需要校验的方法名(首字母大写)()的方式,如:
public void validateLogin(){}只对 login() 方法进行校验
public void validateUpdate(){}只对 update() 方法进行校验

structs.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="default" namespace="/" extends="struts-default">

        <action name="user_*" method="{1}" class="action.UserAction">
            <result>/index.jsp</result>
            <result name="update">/index.jsp</result>
            <result name="input">/login.jsp</result>
        </action>
    </package>
</struts>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>structs2Validator</display-name>
  <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
     <%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
index.jsp
</body>
</html>

校验示例2-在xml中验证

在上例基础上更新

UserAction.java

//package action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import model.User;

@SuppressWarnings("serial")
public class UserAction extends ActionSupport implements ModelDriven<User>{

    private User user = new User();//这里需要实例化

    public String login(){
        System.out.println(user.toString());
        System.out.println("执行了login");
        return "login";
    }
    public String update(){

        System.out.println("执行了update");
        return "update";
    }

    @Override
    public User getModel() {

        return user;
    }
}

校验文件的命名规则是ActionName-validation.xml,需放在action类的同一包下

UserAction-validation.xml

<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>
    <field name="username">
    <!-- 首先调用trim()方法去掉空格,然后判断用户名是否为空 -->
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>用户名不能为空!</message>
        </field-validator>
    </field>

     <field name="password">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>密码不能为空!</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="trim">true</param>
            <param name="minLength">4</param>
            <param name="maxLength">10</param>
            <message>密码长度要4-10之间!</message>
        </field-validator>
    </field>
</validators>

上面的xml校验配置文件会对所有的action方法进行拦截

xml配置方式对指定的action方法实现输入校验

校验文件的取名应为

ActionClassName-ActionName-validation.xml

例如:
在下面的action配置中

<action name="user_*" method="{1}" class="action.UserAction">
            <result name="login">/index.jsp</result>
            <result name="update">/index.jsp</result>
            <result name="input">/login.jsp</result>
</action>
public class UserAction extends ActionSupport{
    public String login(){ 
        return "login";
    }
    public String login(){
        return "update";
    }
}

校验文件名

UserAction-validation.xml 对UserAction中所有方法校验

UserAction-user_login-validation.xml 只对login方法校验

UserAction-user_update-validation.xml 只对update方法校验

系统提供的校验器如下

required (必填校验器,要求field的值不能为null)

requiredstring (必填字符串校验器,要求field的值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)

stringlength (字符串长度校验器,要求field的值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)

regex (正则表达式校验器,检查被校验的field是否匹配一个正则表达式.expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)

int (整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)

double (双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)

fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定

ognl 表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)

email (邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址)

url (网址校验器,要求如果field的值非空,则必须是合法的url地址)

date (日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)

conversion (转换校验器,指定在类型转换失败时,提示的错误信息)

visitor (用于校验action中的复合属性,它指定一个校验文件用于校验复合属性中的属性)

expression (OGNL表达式校验器,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中)

校验器的使用示例

required  必填校验器
<field-validator type="required">
       <message>性别不能为空!</message>
</field-validator>

requiredstring  必填字符串校验器
<field-validator type="requiredstring">
       <param name="trim">true</param>
       <message>用户名不能为空!</message>
</field-validator>

stringlength:字符串长度校验器
<field-validator type="stringlength">
 <param name="maxLength">10</param>
 <param name="minLength">2</param>
 <param name="trim">true</param>
 <message><![CDATA[产品名称应在2-10个字符之间]]></message>
</field-validator>

email:邮件地址校验器
<field-validator type="email">
 <message>电子邮件地址无效</message>
</field-validator>

regex:正则表达式校验器
<field-validator type="regex">
     <param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
     <message>手机号格式不正确!</message>
</field-validator>

int:整数校验器
<field-validator type="int">
 <param name="min">1</param>
 <param name="max">150</param>
 <message>年龄必须在1-150之间</message>
</field-validator>

字段OGNL表达式校验器
<field name="imagefile">
 <field-validator type="fieldexpression">
  <param name="expression"><![CDATA[imagefile.length() <= 0]]></param>
  <message>文件不能为空</message>
 </field-validator>
</field>

XML校验的特点

当为某个action提供了ActionClassName-validation.xmlActionClassName-ActionName-validation.xml两种规则的校验文件时,系统按下面顺序寻找校验文件:

1。AconClassName-validation.xml
2。ActionClassName-ActionName-validation.xml

系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于action方法的校验。如果两个校验文件中指定的校验规则冲突,则只使用后面文件中的校验规则。

当action继承了另一个action,父类action的校验文件会先被搜索到。

假设UserAction继承BaseAction:

<action name="user" class="cn.itcast.action.UserAction" method="{1}">
</action>

访问上面 action,系统先搜索父类的校验文件:BaseAction-validation.xmlBaseAction-user-validation.xml,接着搜索子类的校验文件: UserAction-validation.xmlUserAction-user-validation.xml。应用于上面 action 的校验规则为这四个文件的总和。

国际化

火狐浏览器的选项,内容,设置语言

这里写图片描述

servlet通过读取不同的properties文件显示文字,实现国际化

I18NServlet.java

//package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/** 
 * Title: I18NServlet
 * Description: 读取不同的properties文件,测试国际化
 * @author Peng
 * @date 下午10:07:42
 */
@WebServlet("/I18NServlet")
public class I18NServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    public I18NServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //Locale local = Locale.getDefault();//读取本地机器语言编码zh_CN
        //System.out.println(local);
        Locale local1 = request.getLocale();//读取浏览器页面语言编码zh_CN
        System.out.println(local1);
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out =response.getWriter();
        Properties prop = new Properties();
        prop.load(this.getClass().getResourceAsStream(
                "/aa_"+local1.toString()+".properties"));
        out.println(prop.getProperty("aa"));

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      
        doGet(request, response);
    }

}

两个properties文件

aa_en_US.properties

aa=Hello

aa_zh_CN.properties

aa=\u4F60\u597D

把IE浏览器的语言格式改变为en_US,输出的将是Hello


资源文件的命名格式如下:

baseName_language_country.properties
baseName_language.properties
baseName.properties

其中baseName是资源文件的基本名,我们可以自定义,但language和country必须是java支持的语言和国家。

中国大陆: baseName_zh_CN.properties
美国: baseName_en_US.properties

对于中文的属性文件,我们编写好后,应该使用jdk提供的native2ascii 命令把文件转换为unicode编码的文件。命令的使用方式如下:

native2ascii  源文件.properties  目标文件.properties

配置全局资源与输出国际化信息

当准备好资源文件之后,我们可以在struts.xml中通过struts.custom.i18n.resources常量把资源文件定义为全局资源文件,如下:

<constant name="struts.custom.i18n.resources" value="aa"></constant>

value 为资源文件的基本名
aa_zh_CN.properties,aa_en_US.properties等,对应读取aa开头的资源文件

在 JSP 页面中使用<s:text name=""/>标签输出国际化信息

<s:text name="user"/>

在表单标签中,通过key属性指定资源文件中的key,value显示

<s:textfield name="realname" key="user"/>

在Action类中,可以继承 ActionSupport,使用getText()方法得到国际化信息,该方法的第一个参数用于指定资源文件中的key。

System.out.println(this.getText("aa"));
System.out.println(this.getText("user"));

示例

I18NAction.java

//package action;

import com.opensymphony.xwork2.ActionSupport;

public class I18NAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println(this.getText("aa"));
        System.out.println(this.getText("user"));
        return SUCCESS;
    }
}

aa_en_US.properties

aa=Hello
user=json

aa_zh_CN.properties

aa=你好
user=杰森

structs.xml

<constant name="struts.custom.i18n.resources" value="aa"></constant>
    <package name="i18n" namespace="/" extends="struts-default">    
        <action name="i18n"  class="action.I18NAction">
            <result >/1.jsp</result>        
        </action>       
    </package>

1.jsp

<body>
    这里是1.jsp <br/>
    <s:text name="user"/><br/>
    <s:textfield name="realname" key="user"/>
</body>

国际化—输出带占位符的国际化信息

资源文件中的内容如下:

aa_en_US.properties

aa=Hello
user=json
welcome=hello{0},{1}

aa_zh_CN.properties

aa=你好
user=杰森
welcome=hello{0},{1}

在jsp页面中输出带占位符的国际化信息

<s:text name="welcome">
     <s:param>德玛西亚</s:param>
     <s:param>勇士长存</s:param>
</s:text>

在Action类中获取带占位符的国际化信息,可以使用getText(String key, String[] args)getText(String aTextName, List args)方法。

示例:

aa_en_US.properties

aa=Hello
user=json
welcome=hello{0},{1}

aa_zh_CN.properties

aa=你好
user=杰森
welcome=hello{0},{1}

1.jsp

<body>
    这里是1.jsp <br/>
    标签输出:<s:text name="user"/><br/>
    表单标签:<s:textfield name="realname" key="user"/><br/>
    自定义输出占位符的文字,下面输入什么,就输出什么,与资源文件无关<br/>
    <s:text name="welcome">
        <s:param>德玛西亚</s:param>
        <s:param>勇士长存</s:param>
    </s:text>
</body>

I18NAction.java

public class I18NAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println(this.getText("aa"));
        System.out.println(this.getText("user"));
        System.out.println(this.getText("welcome", new String[]{"呆萌","有毒"}));
        return SUCCESS;
    }

}

控制台输出,由I18NAction输出的内容:

十一月 16, 2016 11:25:52 上午 org.apache.catalina.core.StandardContext reload
信息: Reloading Context with name [/structsi18n] is completed
你好
杰森
hello呆萌,有毒

1.jsp 输出的内容:

这里写图片描述

国际化—包范围资源文件

在一个大型应用中,整个应用有大量的内容需要实现国际化,如果我们把国际化的内容都放置在全局资源属性文件中,显然会导致资源文件变的过于庞大、臃肿,不便于维护,这个时候我们可以针对不同模块,使用包范围来组织国际化文件。

方法如下:
在java的包下放置package_language_country.properties资源文件,package为固定 写法,处于该包及子包下的 action 都可以访问该资源。
当查找指定 key 的消息时,系统会先从 package 资源文件查找,当找不到对应的key时,才 会从常量struts.custom.i18n.resources指定的资源文件中寻找。
例如:

在 action 包下有 package_zh_CN.properties文件,则action包及其子包下,都可以使用这个资源文件。

国际化—Action范围资源文件

我们也可以为某个 action 单独指定资源文件,方法如下:

在Action类所在的路径,放置ActionClassName_language_country.properties资源文件,ActionClassName 为 action 类的简单名称。

当查找指定key的消息时,系统会先从ActionClassName_language_country.properties资源文件查找,如 果没有找到对应的key,然后沿着当前包往上查找基本名为 package 的资源文件,一直找到最顶层包。如果还没有找到对应的key,最后会从常量struts.custom.i18n.resources指定的资源文件中寻 找

国际化—JSP中直接访问某个资源文件

struts2为我们提供了<s:i18n>标签,使用<s:i18n>标签我们可以在类路径下直接从某个资源文件中获取国际化数据,而无需任何配置:

<s:i18n name="jxust">
    <s:text name=“welcome”/>
</s:i18n>

jxust为类路径下资源文件的基本名。

如果要访问的资源文件在类路径的某个包下,可以这样访问:

<s:i18n name=“cn/jxust/action/package">
   <s:text name="welcome">
    <s:param>江西理工大学</s:param>
   </s:text>
</s:i18n>

上面访问cn.jxust.action包下基本名为package的资源文件。

xml中校验配置全局资源与输出国际化信息

接着上面的xml中校验的例子

这里写图片描述

UserAction-validation.xml

<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>
    <field name="username">
    <!-- 首先调用trim()方法去掉空格,然后判断用户名是否为空 -->
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="errors.username"></message>
        </field-validator>
    </field>

     <field name="password">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="errors.password1"></message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="trim">true</param>
            <param name="minLength">4</param>
            <param name="maxLength">10</param>
            <message key="errors.password2"></message>
        </field-validator>
    </field>
</validators>

errors_en_US.properties

errors.username=name is null!
errors.password1=password is null!
errors.password2=password length is error!

errors_zh_CN.properties

errors.username=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A\uFF01
errors.password1=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A\uFF01
errors.password2=\u5BC6\u7801\u957F\u5EA6\u89814-10\u4E4B\u95F4\uFF01

structs.xml 需要这个常量

<constant name="struts.custom.i18n.resources" value="errors"></constant>

login.jsp

<body>
    <%-- 读取errors.username:<s:text name="errors.username"/><br/> --%>
    <%-- 表单标签读取value值<s:textfield name="realname" key="errors.username"/> --%>
    <s:fielderror ></s:fielderror>
    <form action="user_login.action" method="post">
    姓名:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    mobile:<input type="text" name="mobile"/><br/>
    <input type="submit"value="登录"> 
    </form>
    <a href="user_update.action">update</a>
</body>

执行结果:
浏览器为英文的前提下
这里写图片描述
浏览器为中文
这里写图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值