Struts2表单验证、Struts2的国际化-day04上

第一节 Struts2表单验证

1.1 服务端Action验证的两种方式

第一种

  • struts2自带表单字段的验证

    • 第一种重写validate方法,如果数据不对,可以往FieldError添加字段错误信息
      • 注意:
      • 1.表单一定要用struts的标签:s:form/s:textfield
      • 2.addFieldError里的key,是表单的name的值(否则报错)
      • 3.validate对于Action来说是全局,也就是对action的所有方法都会拦截验证
      • 4.在不需要验证的action方法上,可以声明一个注解@SkipValidation,忽略校验
  • UserAction.java

package com.it.web.action;
import com.it.model.User;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.interceptor.validation.SkipValidation;

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

public class UserAction extends ActionSupport implements ModelDriven<User> {
    
    

	private User user = new User();
	@Override
	public User getModel() {
    
    
		return user;
	}
	
	@Override
	public void validate() {
    
    
		//判断用户名是否为空
		//if(username == null && "".equals(username))
		if(StringUtils.isEmpty(user.getUsername())){
    
    
			addFieldError("username", "用户名不能为空");
		}
		
		//判断密码是否为空
		if(StringUtils.isEmpty(user.getPassword())){
    
    
			addFieldError("password", "密码不能为空");
		}
	}
	
	public String register(){
    
    
	//com.opensymphony.xwork2.validator.validators.RequiredStringValidator
		System.out.println("register方法....");
		System.out.println(user);
		return NONE;
	}

	/**
	 * 返回一个列表
	 * @return
	 */
	//@SkipValidation
	public String list(){
    
    
		return "list";
	}
	
}

validate对于Action来说是全局,也就是action的所有方法都会拦截验证,执行list测试方法(如果不使用注解@SkipValidation),直接访问list,会报错,无法访问到userlist.jsp页面,因为validate验证方法全局性,所有方法都会被它验证。

  • register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>
<s:head></s:head>
</head>
<body>

<hr>
<!-- struts表单的特点
1.action不需要写项目名,会自动加
2.会给表单里面的内容放在table中,并加上样式
3.struts的表单项必须要有name
 -->
Struts的Form标签<br>
<%-- <s:fielderror></s:fielderror> --%>
<s:form action="/user/register.action">
	<!--  
	requiredLabel:代表必填项目
	requiredPosition:必填*号位置
	showPassword:回显时,密码还在
	-->
	<s:textfield name="username" label="用户名" requiredLabel="true" requiredPosition="left"></s:textfield>
	<s:password name="password" label="密码" showPassword="true"></s:password>
	<s:textfield name="birthday" label="生日"></s:textfield>
	<%-- <s:checkbox name="hobby" label="写代码" value="写代码"></s:checkbox>
	<s:checkbox name="hobby" label="泡妞" value="泡妞"></s:checkbox>
	<s:checkbox name="hobby" label="买房" value="买房"></s:checkbox> --%>
	<!-- list使用的OGNL表达式 -->
	<s:checkboxlist list="#{
     
     '写代码':'写代码','泡妞':'泡妞','买房':'买房'}" label="爱好" name="hobby"></s:checkboxlist>
	<s:radio list="#{
     
     'true':'已婚','false':'未婚'}" name="married" label="是否已婚"></s:radio>
	<s:submit value="注册"></s:submit>
</s:form>
</body>
</html>
  • struts.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>

	<!-- 开发模式 -->
	<constant name="struts.devMode" value="true"></constant>
	
	<!-- 设置参数 -->
	<package name="p1" extends="struts-default">
		<action name="register" class="com.it.web.action.UserAction" method="register">
			<!-- input:回显,出现错误后,显示哪个界面 -->
			<result name="input">/register.jsp</result>
		</action>
		<action name="list" class="com.it.web.action.UserAction" method="list">
			<result name="list">/userlist.jsp</result>
		</action>
	</package>
	
</struts>

  • userlist.jsp:测试方法,随便写一句话
  • 效果
    在这里插入图片描述

第二种

  • 第二种:写一个方法,格式:validate+方法名(第一个字母大写【如:validateRegister】

  • 注意:只针对方法有效,它是一个局部字段校验

  • UserAction.java中修改部分代码,去掉此方法的@Override,否则报错,因为validateRegister不是ActionSupport中的方法

public void validateRegister() {
    
    
		//判断用户名是否为空
		//if(username == null && "".equals(username))
		if(StringUtils.isEmpty(user.getUsername())){
    
    
			addFieldError("username", "用户名不能为空");
		}
		
		//判断密码是否为空
		if(StringUtils.isEmpty(user.getPassword())){
    
    
			addFieldError("password", "密码不能为空");
		}
	}

validateRegister只针对方法有效,它是一个局部字段校验,此时不使用注解@SkipValidation,直接访问list,也能访问得到
在这里插入图片描述

1.2 xml声明式验证

全局式声明方式

  • 在action包中声明UserAction-validation.xml文件
  • 这种方式配置是全局配置,所有action的方法都会拦截验证
  • 如果其它方法不想验证,可配置@SkipValidation注解
  • dtd约束可以在xwork-core的jar包中找

xml方式配置的文件名前缀要与Action类名一致

在这里插入图片描述

  • UserAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
  		"-//Apache Struts//XWork Validator 1.0.3//EN"
  		"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
  		<!--dtd在xwork-core-2.3.33.jar中可以找到-->
<validators>
	<!-- 第一种校验字段方式 :field-->
	<field name="username">
		<field-validator type="requiredstring">
			<param name="fieldName">username</param>
			<message>用户名不能为空-xml</message>
		</field-validator>
	</field>
	
	<!-- 第二种校验字段方式 :validator更简便-->
	<validator type="requiredstring">
		<param name="fieldName">password</param>
		<message>密码不能为空-xml</message>
	</validator>
</validators>
  • 效果
    在这里插入图片描述

全局声明方式,所有action的方法都会拦截验证,此时访问list无法访问到
在这里插入图片描述

局部声明方式

  • 在action包中声明UserAction-register-validation.xml文件
    声明方式 【Action类名-方法名-validation.xml】
  • xml内容与上面的一样
    在这里插入图片描述

此时再访问list,可以访问到
因为此时UserAction-register-validation.xml只验证它的register方法
在这里插入图片描述

其它

  • struts默认有很多种验证器类型,声明在default.xml中
  • 注意default.xml的位置

validators里有很多struts的默认验证配置
default.xml的位置:如下图
在这里插入图片描述

例如:密码不能大于6位的配置

<validator type="stringlength">
	<param name="fieldName">password</param>
	<param name="maxLength">6</param>
	<message>密码不能大于6位</message>
</validator>

在这里插入图片描述

1.3 验证器综合案例

add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>
<s:head></s:head>
</head>
<body>

<hr>
<s:debug></s:debug><%--debug模式,能看到更多的错误信息--%>
添加学生
<s:actionerror/><%--拿到actionError里的 密码不一致 信息--%>
<s:form action="/stu/add.action">
	<s:textfield name="username" label="用户名"/>
	<s:textfield name="age" label="年龄"/>
	<s:textfield name="email" label="邮箱"/>
	<%-- <s:password name="password" label="密码"/> --%>
	<s:textfield name="password" label="密码"/>
	<s:textfield name="repassword" label="确认密码"/>
	<s:textfield name="score" label="成绩"/>
	<s:textfield name="url" label="个人主页"/>
	<s:radio list="{
     
     '',''}" name="gender" label="性别"></s:radio>
	<s:submit value="提交"/>	
</s:form>
</body>
</html>

Student.java

package com.it.model;

public class Student {
    
    
	private String username;//不能为空,去空字符串
	private int age;//18~100
	private String email;//正确邮箱格式
	private String password;//3~8
	private String repassword;//与密码一至
	private int score;//必须是自然数
	private String url;//必须是一个路径 http://
	private String gender;//性别,只有男和女
	public String getUsername() {
    
    
		return username;
	}
	public void setUsername(String username) {
    
    
		this.username = username;
	}
	public int getAge() {
    
    
		return age;
	}
	public void setAge(int age) {
    
    
		this.age = age;
	}
	public String getEmail() {
    
    
		return email;
	}
	public void setEmail(String email) {
    
    
		this.email = email;
	}
	public String getPassword() {
    
    
		return password;
	}
	public void setPassword(String password) {
    
    
		this.password = password;
	}
	public String getRepassword() {
    
    
		return repassword;
	}
	public void setRepassword(String repassword) {
    
    
		this.repassword = repassword;
	}
	public int getScore() {
    
    
		return score;
	}
	public void setScore(int score) {
    
    
		this.score = score;
	}
	public String getUrl() {
    
    
		return url;
	}
	public void setUrl(String url) {
    
    
		this.url = url;
	}
	public String getGender() {
    
    
		return gender;
	}
	public void setGender(String gender) {
    
    
		this.gender = gender;
	}
	@Override
	public String toString() {
    
    
		return "Student [username=" + username + ", age=" + age + ", email=" + email + ", password=" + password
				+ ", repassword=" + repassword + ", score=" + score + ", url=" + url + ", gender=" + gender + "]";
	}
		
}

StudentAction.java

package com.it.web.action;


import com.it.model.Student;
import com.it.model.User;
import com.it.service.IUserService;
import com.it.service.impl.UserServiceImpl;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.interceptor.validation.SkipValidation;

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

public class StudentAction extends ActionSupport implements ModelDriven<Student> {
    
    
	
	private Student stu = new Student();
	@Override
	public Student getModel() {
    
    
		// TODO Auto-generated method stub
		return stu;
	}
	 
	public String add(){
    
    
		//com.opensymphony.xwork2.validator.validators.RequiredFieldValidator
		//com.opensymphony.xwork2.validator.validators.RequiredStringValidator
		//com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator
		//com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator
		//com.opensymphony.xwork2.validator.validators.ExpressionValidator
		//com.opensymphony.xwork2.validator.validators.RegexFieldValidator
		System.out.println(stu);
		return NONE;
	}
}

struts.xml

<package name="p2" extends="struts-default" namespace="/stu">
		<action name="add" class="com.it.web.action.StudentAction" method="add">
			<result name="input">/add.jsp</result>
		</action>
</package>

StudentAction-add-validation.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
  		"-//Apache Struts//XWork Validator 1.0.3//EN"
  		"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
	<!--
	 1.  private String username;//不能为空,去空字符串
		 requiredstring 比 required 好一点,会自动去除空格
	 -->
	<validator type="requiredstring">
		<param name="fieldName">username</param>
		<message>用户名不能为空</message>
	</validator>
	
	
	<!--2.private int age;//18~100 
	  1.表单的类型,会根据模型的属性类型去校验
	 -->
	 <validator type="int">
	 	<param name="fieldName">age</param>
	 	<param name="min">18</param>
	 	<param name="max">100</param>
	 	<message>年龄必须在18~100</message>
	 </validator>
	
	
	<!-- 3.private String email;//正确邮箱格式-->
	<validator type="requiredstring">
		<param name="fieldName">email</param>
		<message>邮箱不能为空</message>
	</validator>
	 <validator type="email">
	 	<param name="fieldName">email</param>
	 	<message>邮箱格式不正确【如:[email protected]</message>
	 </validator>
		 
	 
	 <!--4. private String password;//3~8 -->
	 <validator type="requiredstring">
		<param name="fieldName">password</param>
		<message>密码不能为空</message>
	</validator>
	<validator type="stringlength">
		<param name="fieldName">password</param>
		<param name="minLength">3</param>
		<param name="maxLength">8</param>
		<message>密码长度为3~8</message>
	</validator>
	
	<!-- 5.private String repassword;//与密码一至 -->
	<validator type="expression">
		<param name="expression">
			<![CDATA[ password == repassword]]>
		</param>
		<message>密码不一致</message>
	</validator>
	
	<!-- 6.private int score;//必须是自然数
		regex :正则
	 -->
	<validator type="regex">
		<param name="fieldName">score</param>
		<param name="regexExpression">\d+</param>
		<message>分数必须为数字</message>
	</validator>
	
	
	<!-- 	private String url;//必须是一个路径 http:// -->
	<validator type="url">
		<param name="fieldName">url</param>
		<message>URL格式不合法,以 http://开头</message>
	</validator>
	
	<!-- 	private String gender;//性别必填,只有男和女 -->
	<validator type="required">
		<param name="fieldName">gender</param>
		<message>性别必选</message>
	</validator>
</validators>

效果:

在这里插入图片描述

第二节 Struts2的国际化

2.1 什么是国际化

  • 软件的国际化:软件开发时要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据

2.2 国际化使用的场景

2.3 固定文本的国际化

  • 例如:消息提示,错误提示和菜单,导航栏等等固定文本。

第一步:创建一个消息资源包

  1. 一个资源包由多个文件组成,这些文件名都有命名规范:主要文件名_语言代码_国家代码.properties
  2. 语言代码和国家代码:由iso规定的。
  3. 当文件只有主要文件名.properties时,表明它是默认资源包。浏览器会根据不同的语言环境找对应语言环境的资源包。
  4. 当没有时,找默认的。
  5. 每个资源包的内容都由相同的key和对应语言环境的value组成。
  6. 例如:
    • message_zh_CN.properties(zh代表语言代码中文,CN国家代码中国)
    • message_zh_HK.properties(zh中文,HK香港)
    • message_en_US.properties(en英文,US美国)
      在这里插入图片描述

第二步:读取资源包中的内容

  • Java提供ResourceBundle类可以读取资源包的国际化配置文件
  • I18NTest.java
package com.it.test;

import java.util.Locale;
import java.util.ResourceBundle;

import org.junit.Test;

public class I18NTest {
    
    

	@Test
	public void test1(){
    
    
		//读取国际化资源数据
		//使用ResourceBundle读取数据
		//baseName=包名+文件名
		//默认读取是中文
		//ResourceBundle rb = ResourceBundle.getBundle("resources.message");
		
		//指定读取某个国家国际化数据
		//ResourceBundle rb = ResourceBundle.getBundle("resources.message", Locale.US);
		ResourceBundle rb = ResourceBundle.getBundle("resources.message", Locale.CHINA);
		
		System.out.println(rb.getString("login.username"));
		System.out.println(rb.getString("login.password"));
		System.out.println(rb.getString("login.submit"));
	}
}

  • 测试效果
    在这里插入图片描述

第三步:JSP中使用国际化

  • 本质还是java实现
  • login.jsp
<%@page import="java.util.ResourceBundle"%>
<%@page import="java.util.Locale"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>

<hr>
<%
	Locale local = Locale.getDefault();//获取到一个默认的国家语言
	ResourceBundle rb = ResourceBundle.getBundle("resources.message", local);<%-- <%=local.US %> --%>
%>
<%=local %><%-- <%=local.US %> --%>
<form action="${pageContext.request.contextPath}/login.action">
	<%=rb.getString("login.username")%><input type="text" name="username"><br>
	<%=rb.getString("login.password")%><input type="password" name="password"><br>
	<input type="submit" value="<%=rb.getString("login.submit")%>">
</form>
</body>
</html>
  • zh_CN默认中文格式
    在这里插入图片描述
  • en_US
    在这里插入图片描述

第四步:使用jstl标签来国际化

  • JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
  • JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。
  • 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
  1. 首先需要在项目中导入两个jar包
    在这里插入图片描述
  2. Jsp中代码截图如下
    在这里插入图片描述

2.4 Struts提供的国际化

  • 前面的国际化与struts无关

第一步:配置资源包

  1. 配置全局的资源包
  • 在struts.xml中配置
	<!-- 开发模式 -->
	<constant name="struts.devMode" value="true"></constant>
	
	<!-- 配置全局的国际化 -->
	<constant name="struts.custom.i18n.resources" value="resources.message"/>
	
  • 代码同上
    在这里插入图片描述
    在这里插入图片描述

  • login2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>

<hr>
<form action="${pageContext.request.contextPath}/login.action">
		<s:text name="login.username"/> <input type="text" name="username"><br>
		<s:text name="login.password"/><input type="password" name="password"><br>
		<input type="submit" value="<s:text name="login.submit"/>">
</form>
</body>
</html>
  • 效果:
    在这里插入图片描述
  • 在IE浏览器设置语言首选项后刷新浏览器
    在这里插入图片描述
  1. 配置包范围的资源包
  • 资源包名称命名规范:package_语言代码_国家代码.properties(固定的)。以此种命名方式的资源包能被该包及其子包中的动作类访问。

  • 优先级:高于全局消息资源包
    在这里插入图片描述
    在这里插入图片描述

  • 写一个UserAction.java

package com.it.web.action;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{
    
    

	public String login(){
    
    
		//com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor
		//读取资源包数据-读取资源顺序【局部-包级别-全局】
		System.out.println(getText("login.username"));
		System.out.println(getText("login.password"));
		System.out.println(getText("login.submit"));
		return NONE;
	}
}
  • 在struts.xml中配置
	<!-- 开发模式 -->
	<constant name="struts.devMode" value="true"></constant>
	
	<!-- 配置全局的国际化 -->
	<constant name="struts.custom.i18n.resources" value="resources.message"/>
	
	<package name="p1" extends="struts-default">
		<action name="login" class="com.it.web.action.UserAction" method="login">	
		</action>
	</package>
  • 访问路径:http://localhost:8080/day04_struts2_demo3/login
  • 效果:
    在这里插入图片描述
  1. 局部消息资源包
  • 资源包名称命名规范:动作类名称_语言代码_国家代码.properties。以此种命名方式的资源包,只为动作类服务。
  • 优先级最高(就近原则)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  1. Struts2中资源包的搜索顺序:
    在这里插入图片描述

第二步:读取资源包内容

  1. jsp读取资源包内容
  • 使用struts的标签s:text获取国际化内容,上面的jsp代码中已使用
    在这里插入图片描述
  1. Action读取资源包内容
  • 使用ActionSupport的getText方法,可以读取到资源包的内容
  • 也就是说这个Action一定要继承ActionSupport
  • 这种在实际开发中几乎不用
    在这里插入图片描述
  1. 自由指定读取资源包
  • 在jsp页面可以使用s:i18n标签指向读取的国际资源包文件
    在这里插入图片描述
  • 修改后的login2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>
<hr>
<form action="${pageContext.request.contextPath}/login.action">
	<s:i18n name="com.it.web.package">
		<s:text name="login.username"/> <input type="text" name="username"><br>
		<s:text name="login.password"/><input type="password" name="password"><br>
		<input type="submit" value="<s:text name="login.submit"/>">
	</s:i18n>
</form>
</body>
</html>
  • 效果:指定访问包范围内资源文件
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43414199/article/details/107869788
今日推荐