六Struts2 国际化
国际化简介
国际化(Internationlization),通俗地讲,就是让软件实现对多种语言的支持;
Struts2 国际化设置
<constantname=“struts.custom.i18n.resources"value=“java1234”>
<s:textname=”"></s:text> 访问国际化资源
新建项目HeadFirstStruts2Chap06
->struts.xml
<struts>
<constant name="struts.custom.i18n.resources" value="java1234"></constant>
</struts>
->新建java1234.properties 这是用unicode编码
userName=\u7528\u6237\u540d
password=\u5bc6\u7801
login=\u767b\u5f55
->新建java1234_en_US.properties
userName=userName
password=password
login=login
->新建java1234_zh_CN.properties
userName=\u7528\u6237\u540d
password=\u5bc6\u7801
login=\u767b\u5f55
->新建login.jsp OGNL标签记得引入
<table>
<tr>
<td><s:text name="userName"></s:text></td>
<td>
<input type="text"/>
</td>
</tr>
<tr>
<td><s:text name="password"></s:text></td>
<td>
<input type="text"/>
</td>
</tr>
<tr>
<td>
<input type="button" value="<s:text name='login'></s:text>"/>
</td>
</tr>
</table>
->启动项目http://localhost:8080/HeadFirstStrutsChap06/login.jsp
在英文环境下面显示英文 在中文环境下显示中文
在国际化页面里设参数
->新建java1234.properties 这是用unicode编码
userName=\u7528\u6237\u540d
password=\u5bc6\u7801
login=\u767b\u5f55
welcomeInfo=\u6b22\u8fce{0}
->新建java1234_en_US.properties
userName=userName
password=password
login=login
welcomeInfo=welcome{0}
->新建java1234_zh_CN.properties
userName=\u7528\u6237\u540d
password=\u5bc6\u7801
login=\u767b\u5f55
welcomeInfo=\u6b22\u8fce{0}
->新建welcome.jsp
<s:text name="welcomeInfo">
<s:param>Jack</s:param>
</s:text>
->启动项目http://localhost:8080/HeadFirstStrutsChap06/welcom.jsp
在英文环境下面显示英文 在中文环境下显示中文
七Struts2 验证框架
Struts2 验证简介
Struts2 基于 Struts2 拦截器,为开发者提供了一套易用的验证框架,并可扩展;一般的验证都支持;
Struts2验证有手动验证和验证码验证,Struts推荐采用配置文件的方式进行数据校验
下面为步骤:
a.继承ActionSupport类
b.修改struts2.xml文件:删除method属性
c.在需要验证的Action类的相同包下,写一个"类名-validation.xml"文件
d.加入头信息以具有提示功能
注意两点:
1
2
Struts2 内置验证
1普通字段验证;
2验证表达式;
新建项目HeadFirstStruts2Chap07
新建model User.java
package com.java1234.model;
public class User {
private String userName;
private String name;
private int age;
private String email;
private String homePage;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 getHomePage() {
return homePage;
}
public void setHomePage(String homePage) {
this.homePage = homePage;
}
@Override
public String toString() {
return "User [userName=" + userName + ", name=" + name + ", age=" + age
+ ", email=" + email + ", homePage=" + homePage + "]";
}
}
->新建Action RegisterAction.java
package com.java1234.action;
import com.java1234.model.User;
import com.opensymphony.xwork2.ActionSupport;
public class RegisterAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println("传入的用户:"+user);
return SUCCESS;
}
}
->struts.xml
<struts>
<package name="manager" extends="struts-default">
<action name="registerAction" class="com.java1234.action.RegisterAction">
<result name="input">/register.jsp</result> //验证失败
<result name="success">/success.jsp</result> //验证成功
</action>
</package>
</struts>
->新建register.jsp
<s:actionerror/>//这个是用来验证表达式时要加上的
用户注册
<s:form action="/registerAction" method="post">
<s:textfield name="user.userName" label="用户名"></s:textfield>
<s:textfield name="user.name" label="真实姓名"></s:textfield>
<s:textfield name="user.age" label="年龄"></s:textfield>
<s:textfield name="user.email" label="邮件"></s:textfield>
<s:textfield name="user.homePage" label="主页"></s:textfield>
<s:submit value="注册"></s:submit>
</s:form>
->新建success.jsp
注册成功
->新建配置文件RegisterAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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="user.userName">
<field-validator type="requiredstring">
<message>请输入用户名</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>用户名必须在${minLength}和${maxLength}之间</message>
</field-validator>
</field>
<field name="user.name">
<field-validator type="requiredstring">
<message>请输入姓名</message>
</field-validator>
</field>
<field name="user.age">
<field-validator type="int">
<param name="min">18</param>
<message>年龄必须满18周岁</message>
</field-validator>
</field>
<field name="user.email">
<field-validator type="requiredstring">
<message>请输入邮件</message>
</field-validator>
<field-validator type="email">
<message>邮件格式不对</message>
</field-validator>
</field>
<field name="user.homePage">
<field-validator type="requiredstring">
<message>请输入主页</message>
</field-validator>
<field-validator type="url">
<message>主页格式不对</message>
</field-validator>
</field>
//验证表达式
<validator type="expression">
<param name="expression"><![CDATA[!user.name.equals(user.userName)]]></param>
<message>用户名和真实姓名不能相同</message>
</validator>
</validators>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap07/register.jsp
执行结果
当输入信息不满足条件时,点击提交,会给出相应的验证信息
自定义验证
struts2为我们提供了一种很好的范式,我们直接引入,也可以自己写
原理:先去找validators.xml
->复制validators.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator Config 1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">
<validators>
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
->自己写一个关键字验证器
->新建包com.java1234.validators
新建SensitiveWordValidators.java
package com.java1234.validators;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;
public class SensitiveWordValidators extends FieldValidatorSupport{
//要继承FieldValidatorSupport,重写方法
@Override
public void validate(Object object) throws ValidationException {
//这里面要写要检查哪个字段
String fieldName=this.getFieldName();
String value=this.getFieldValue(fieldName, object).toString();
if(!check(value)){
//相当于添加错误信息,转发到页面
this.addFieldError(fieldName, object);
}
}
public boolean check(String value){
String sensitiveWords[]={"操","你妈"};
for(int i=0;i<sensitiveWords.length;i++){
if(value.indexOf(sensitiveWords[i])>-1){
//
return false;
}
}
return true;
}
}
->要把上面写的验证器加到validators.xml里面
<validator name="sensitive" class="com.java1234.validators.SensitiveWordValidators"/>
</validators>
->写action
新建ValidationAction.java
package com.java1234.action;
import com.java1234.model.User;
import com.opensymphony.xwork2.ActionSupport;
public class ValidationAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
System.out.println("姓名:"+name);
return SUCCESS;
}
}
->新建与action同名的xml文件 ValidationAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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="name">
//系统的验证器
<field-validator type="requiredstring">
<message>请输入姓名</message>
</field-validator>
//自定义的的验证器
<field-validator type="sensitive">
<message>有敏感词汇</message>
</field-validator>
</field>
</validators>
->配置struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manager" extends="struts-default">
<action name="validationAction" class="com.java1234.action.ValidationAction">
<result name="input">/validation.jsp</result>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
->新建validation.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:form action="/validationAction" method="post">
<s:textfield name="name" label="姓名"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
->启动程序http://localhost:8080/HeadFirstSrtuts2Chap07/validation.jsp
运行结果:
若不填姓名就提交,同页面上会提示:请输入姓名
若姓名中含有上面那两个关键字, 同页面上会提示:有敏感词汇,控制器上打印出“姓名:XXX”
若输入正常的名字,会跳转到success.jsp页面,显示登录成功。
八Struts2 文件上传和下载
一Struts2 文件上传
Struts2 文件上传基于 Struts2 拦截器实现;
Struts2 文件上传使用的是 fileupload 组件;
Form 配置 enctype=“multipart/form-data”; //表示以二进制的形式进行上传
Struts2 获取上传文件:name (name 是文件表单的 name);
Struts2 获取上传文件名:name+FileName; Struts2 获取上传文件的类型name+ContentType;
新建项目HeadFirstStruts2Chap08
->新建fileupload.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="upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="java1234"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
->新建success.jsp
文件上传成功
->新建actiom FileUploadAction.java
package com.java1234.action;
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.opensymphony.xwork2.ActionSupport;
public class FileUploadAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private File java1234; // 文件
private String java1234FileName; // 文件名
private String java1234ContentType; // 文件类型
public File getJava1234() {
return java1234;
}
public void setJava1234(File java1234) {
this.java1234 = java1234;
}
public String getJava1234FileName() {
return java1234FileName;
}
public void setJava1234FileName(String java1234FileName) {
this.java1234FileName = java1234FileName;
}
public String getJava1234ContentType() {
return java1234ContentType;
}
public void setJava1234ContentType(String java1234ContentType) {
this.java1234ContentType = java1234ContentType;
}
@Override
public String execute() throws Exception {
System.out.println("文件名:"+java1234FileName);
System.out.println("文件类型:"+java1234ContentType);
String filePath="C:/"+java1234FileName;
File saveFile=new File(filePath);
FileUtils.copyFile(java1234, saveFile);
//相当于把文件copy到本地去
return SUCCESS;
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manager" extends="struts-default">
<action name="upload" class="com.java1234.action.FileUploadAction">
<result name="success">/success.jsp</result>
<result name="input">/fileupload.jsp</result>
<!-- <interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param>
<param name="maximumSize">81101</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> -->
</action>
</package>
</struts>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap08/fileupload.jsp
选择图片上传
发现c盘的规定路径下有了图片
控制台打印出“文件名:XXX.jpg 文件类型:image/jpeg”
二配置文件的大小及类型
<paramname="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param> <paramname="maximumSize">81101</param>
<s:fielderror></s:fielderror>
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manager" extends="struts-default">
<action name="upload" class="com.java1234.action.FileUploadAction">
<result name="success">/success.jsp</result>
<result name="input">/fileupload.jsp</result>
//错误的话,底层返回的是input
//规定上传文件的类型和大小
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg</param>
<param name="maximumSize">81101</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
执行结果:上传一个正常的图片,跳转到success.jsp,文件上传成功
上传一个超过大小的图片,报错
三大文件上传
Struts2 文件上传大小默认是 2M;
在struts.xml中package前面加上下面这句!
<constantname="struts.multipart.maxSize"value="20000000"></constant>
四多文件上传
新建filesupload.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="uploads" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="java1234"/><br/>
文件2:<input type="file" name="java1234"/><br/>
文件3:<input type="file" name="java1234"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
->新建FilesUploadAction.java
package com.java1234.action;
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.opensymphony.xwork2.ActionSupport;
public class FilesUploadAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private File[] java1234; // 文件
private String[] java1234FileName; // 文件名
private String[] java1234ContentType; // 文件类型
public File[] getJava1234() {
return java1234;
}
public void setJava1234(File[] java1234) {
this.java1234 = java1234;
}
public String[] getJava1234FileName() {
return java1234FileName;
}
public void setJava1234FileName(String[] java1234FileName) {
this.java1234FileName = java1234FileName;
}
public String[] getJava1234ContentType() {
return java1234ContentType;
}
public void setJava1234ContentType(String[] java1234ContentType) {
this.java1234ContentType = java1234ContentType;
}
@Override
public String execute() throws Exception {
for(int i=0;i<java1234.length;i++){
System.out.println("文件名:"+java1234FileName[i]);
System.out.println("文件类型:"+java1234ContentType[i]);
String filePath="C:/"+java1234FileName[i];
File saveFile=new File(filePath);
FileUtils.copyFile(java1234[i], saveFile);
}
return SUCCESS;
}
}
->struts.xml
<action name="uploads" class="com.java1234.action.FilesUploadAction">
<result name="success">/success.jsp</result>
<result name="input">/filesupload.jsp</result>
</action>
->执行结果:
上传三个文件,跳转到success.jsp显示文件上传成功。
五Struts2 文件下载
返回的是文件流 <paramname=“contentDisposition”>attachment;filename=${fileName}
返回的方法里面
InputStreamgetInputStream()
->新建FileDownloadAction.java
package com.java1234.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import com.opensymphony.xwork2.ActionSupport;
public class FileDownloadAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String fileName;
public String getFileName() throws Exception{
fileName=new String(fileName.getBytes(),"ISO8859-1");
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public InputStream getInputStream()throws Exception{
File file=new File("C:/1.jpg");
this.fileName="1111";
return new FileInputStream(file);
}
}
->struts.xml
<action name="download" class="com.java1234.action.FileDownloadAction">
<result type="stream">
<param name="contentDisposition">attachment;filename=${fileName}</param>
</result>
</action>
->新建filedownload.jsp
文件下载
->执行结果:点击链接,文件下载到C盘了
九Struts2 防重复提交
重复提交示例演示
新建项目HeadFirstStruts2Chap09
->新建Student.java
package com.java1234.model;
public class Student {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
->新建StudentAction.java
package com.java1234.action;
import java.io.File;
import org.apache.commons.io.FileUtils;
import com.java1234.model.Student;
import com.opensymphony.xwork2.ActionSupport;
public class StudentAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String add() throws Exception {
System.out.println("开始添加学生:"+student);
Thread.sleep(5000);
System.out.println(student.getName()+"添加完成");
return SUCCESS;
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manager" extends="struts-default">
<action name="student" class="com.java1234.action.StudentAction" method="add">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
->新建success.jsp
学生添加成功
->新建student.jsp
<form action="student" method="post" >
姓名:<input type="text" name="student.name"/><br/>
年龄:<input type="text" name="student.age"/><br/>
<input type="submit" value="提交"/>
</form>
->模拟重复提交
输入姓名和年龄,提交,跳转到成功页面,显示“学生添加成功”。控制台上打印出“开始添加学生:Student[name=张三,age=12] 张三添加完成”。
加上Thread.sleep(5000);
点了两次提交,业务上就不合理。
使用<s:token/>标签防重复提交
<s:token></s:token> :加在 form 里;
使用 token 拦截器:
/student.jsp :在 struts.xml 里配置,假如出现重复提 交,则直接回到页面;
<s:actionerror/>:在页面上显示错误信息;
->student.jsp
<s:actionerror/>//显示错误信息
<form action="student" method="post" >
<s:token></s:token> //加上这个,每次提交都有唯一的一个tokenid
姓名:<input type="text" name="student.name"/><br/>
年龄:<input type="text" name="student.age"/><br/>
<input type="submit" value="提交"/>
</form>
->struts.xml
<struts>
<package name="manager" extends="struts-default">
<action name="student" class="com.java1234.action.StudentAction" method="add">
<result name="success">/success.jsp</result>
<result name="invalid.token">/student.jsp</result>
<interceptor-ref name="token"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
->执行结果:
若重复提交,会报错,同页面上显示The form has already been proceed or no token was supplied,please try again.
这种方式的缺点是:有错的的话是显示在页面,但业务上我们需要系统无视重复提交。
使用 tokenSession 拦截器防重复提交
tokenSesssion 拦截器直接无视重复提交的请求;
<interceptor-refname=“tokenSession”>
<interceptor-refname=“defaultStack”>
->struts.xml
<struts>
<package name="manager" extends="struts-default">
<action name="student" class="com.java1234.action.StudentAction" method="add">
<result name="success">/success.jsp</result>
<interceptor-ref name="tokenSession"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
->执行结果:
重复提交后,点击一次后没有反应,你再点一次没有反应的。后台报错。