struts2表单提交数据的验证
硬编码
使用java代码进行的验证配置
public class UserAction extends ActionSupport implements ModelDriven<User>{
// 声明一个user对象
private User user = new User();
// 声明一个注册的动作方法
@SkipValidation
public String register() throws Exception {
return "success";
}
// 验证表单提交参数的方法
// 该方法会验证 本Action类中的所有方法
@Override
public void validate() {
// 判断数据的合法性
if (StringUtils.isEmpty(user.getUsername())) {
System.out.println("走没走");
// 不合法 添加不合法信息
// 参数1 表单中 对应的字段名(name属性的名字)
// 参数2 错误信息
// 当信息不合法的时候 会默认去找 字符串input 结果所对应的页面
this.addFieldError("username", "用户名不能为空");
}
}
@Override
public User getModel() {
return user;
}
}
该类中的多方法跳过验证
方式一:使用注解 @SkipValidation 跳过验证
@SkipValidation
public String query() {
return SUCCESS;
}
方式二:指定要被验证的动作方法
命名规范(小驼峰): validate + 要验证的方法名(首字母大写)
相当于 struts 在验证拦截时会扫描你整个动作类中的方法
查找是否有validate开头的方法和名字后面的动作方法
有就进行拦截,没有就算了
public void validateQuery() {
if (StringUtils.isEmpty(user.getUsername())) {
this.addFieldError("username", "啥也没填");
}
}
软编码
使用配置文件(xml或properties)
<?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.命名规范 动作类名 + - + validation.xml
2.必须跟动作类同包
软编码方式 也会拦截动作类中的所有方法
使用注解 -->
<!-- 验证用户名
name:表示是表单提交的name属性 -->
<field name="username">
<!-- 指定使用的验证器,非空验证
com.opensymphony.xwork2.validator.validators报下的default.xml中 -->
<field-validator type="requiredstring">
<!-- 验证失败的错误提示信息 -->
<message>用户名不能为空</message>
</field-validator>
</field>
</validators>
struts.xml
<struts>
<package name="UserAction" namespace="/" extends="struts-default">
<action name="UserAction_*" class="com.lanou3g.UserAction" method="{1}">
<result name="success">/success.jsp</result>
<!-- 配置一下 表单验证不合法要去的页面 -->
<!-- 注意:如果重定向 相当于重新访问该页面 也会重新创建一个ActionContext出来 这样会导致之前保存的信息丢失 所以要使用请求转发 -->
<result name="input">/register.jsp</result>
</action>
<!-- 测试同类方法是否拦截 -->
<action name="queryAction" class="com.lanou3g.UserAction" method="query">
<result name="success">/success.jsp</result>
<result name="input">/query.jsp</result>
</action>
</package>
</struts>
jsp显示错信息
<!--导入struts标签库-->
<%@ taglib prefix="s" uri="/struts-tags" %>
<!--
取出fieldErrors对应的值
map中username这个键值对的值
[0]数组中取第一个元素
-->
<s:property value="fieldErrors.username[0]"/><br>
注册验证
<form action="${pageContext.request.contextPath }/ValidationAction" method="post">
<!-- 使用el表达式 进行数据回显
把表单中提交的数据 存入param
相当于一个map中
${param.username} .后面是你name属性
-->
用户名<input type="text" name="username" value="${param.username}">
<s:property value="errors.username[0]"/><br>
邮箱<input type="email" name="email" value="${param.email}">
<s:property value="errors.email[0]"/><br>
年龄<input type="text" name="age" value="${param.age}">
<s:property value="errors.age[0]"/><br>
密码<input type="password" name="password" value="${param.password}">
<s:property value="errors.password[0]"/><br>
确认密码<input type="password" name="repassword">
<s:property value="errorMessages[0]"/><br>
网址<input type="url" name="url" value="${param.url}">
<s:property value="errors.url[0]"/><br>
男<input type="radio" name="gender" value="男" ${param.gender=='男'?'checked':'' }/>
女<input type="radio" name="gender" value="女" ${param.gender=='女'?'checked':'' }/>
<s:property value="errors.gender[0]"/><br>
<input type="submit" value="提交">
</form>
<s:debug></s:debug>
ValidationAction
public class ValidationAction extends ActionSupport implements ModelDriven<Customer>{
private Customer customer = new Customer();
public String register() {
return "success";
}
@Override
public Customer getModel() {
return customer;
}
}
ValidationAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator Definition 1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
<validators>
<!--验证用户名-->
<field name="username">
<field-validator type="requiredstring">
<message>请输入用户名</message>
</field-validator>
</field>
<!--年龄-->
<field name="age">
<field-validator type="int">
<!-- int 必须是整数 指定范围 -->
<param name="max">60</param>
<param name="min">18</param>
<message>你年龄不符合要求</message>
</field-validator>
</field>
<!--验证邮箱-->
<field name="email">
<field-validator type="email">
<message>邮箱不对呀</message>
</field-validator>
</field>
<!--验证密码-->
<field name="password">
<field-validator type="requiredstring">
<message>密码不能为空</message>
</field-validator>
<field-validator type="stringlength">
<param name="maxLength">8</param>
<param name="minLength">3</param>
<message>密码长度不符合要求</message>
</field-validator>
</field>
<!--验证url-->
<field name="url">
<field-validator type="url">
<message>url不符合要求</message>
</field-validator>
</field>
<!--性别-->
<field name="gender">
<field-validator type="required">
<message>必须选择性别</message>
</field-validator>
</field>
<!--确认密码
与其他的字段判断方式不同,这是判断两个字段的值
跟标签选择 校验器,校验器类型为表达式-->
<validator type="expression">
<param name="expression">
password == repassword
</param>
<message>两次密码不一致</message>
</validator>
</validators>
struts.xml
<struts>
<package name="UserAction" namespace="/" extends="struts-default">
<action name="ValidationAction" class="com.lanou3g.ValidationAction"
method="register">
<result name="success">/success.jsp</result>
<result name="input">/validation.jsp</result>
</action>
</package>
</struts>
struts上传
UploadAction
public class UploadAction extends ActionSupport{
// 声明一个File[]属性
// 用来接收上传的文件
// 注意:命名规范 这个文件数组的名字 为提交的name属性
private File[] file;
// 声明一个String[]数组 属性
// 用来接收上传文件的名字
// 注意:命名规范 name属性名 + FileName
private String[] fileFileName;
// 上传动作方法
// 上传到服务器 你这个应用下的文件夹
public String upload() {
/*
* 1.获取文件上传的服务器路径
* 2.拼接上传文件夹路径
* 3.在服务器上创建上传的文件夹
* 4.把struts接收到的文件 保存到该路径下
*/
// 获取ServletContext
ServletContext application = ServletActionContext.getServletContext();
// 获取真实路径(服务器的硬盘路径) 传入拼接的文件夹地址
String realPath = application.getRealPath("/upload");
// 根据路径创建文件夹 (判断文件夹不存在 再创建)
// 用这个路径创建一个file对象
File f = new File(realPath);
if (!f.exists()) {
// 不存在就创建
f.mkdir();
}
// 把struts接收过来的文件 放入该文件夹中
// 遍历文件数组 取出每一个文件放入
for (int i = 0; i < file.length; i++) {
// 取出每一个文件放入
File tempFile = file[i];
// 取出每一个对应的文件名
String tempFileName = fileFileName[i];
// 直接将文件重新命名 renameTo(相当于把该文件改个名剪切过去)
tempFile.renameTo(new File(realPath, tempFileName));
}
return "success";
}
// 必须提供get/set方法
public String[] getFileFileName() {
return fileFileName;
}
public File[] getFile() {
return file;
}
public void setFile(File[] file) {
this.file = file;
}
public void setFileFileName(String[] fileFileName) {
this.fileFileName = fileFileName;
}
}
upload.jsp
<!-- 上传文件 必须使用post方式提交表单 -->
<!-- 表单 默认提交的数据类型 enctype-->
<!-- 上传使用的enctype multipart/form-data 多部分上传 -->
<form action="${pageContext.request.contextPath }/UploadAction" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="file" name="file">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
struts.xml
<struts>
<!-- 设置最大上传大小 struts.multipart.maxSize=2097152 -->
<constant name="struts.multipart.maxSize" value="52428800"></constant>
<package name="UserAction" namespace="/" extends="struts-default">
<action name="UploadAction" class="com.lanou3g.UploadAction"
method="upload">
<result name="success" type="redirect">/success.jsp</result>
</action>
</package>
</struts>
struts下载
DownloadAction
public class DownloadAction extends ActionSupport {
// 获取表单传过来的文件名
// 这里会出现文件名的中文乱码问题
// 需要修改fileName的编码格式
private String fileName;
// 声明读取文件的字节流属性
// 把这个流创建出来 其他可以交给struts
// 这个名字没有规范 但是你要告诉struts你给它是哪个流
// 提供set/get 方法
private InputStream fileInputStream;
// 下载方法
public String download() throws FileNotFoundException {
/*
* 1.获取用户要下载的文件的真实路径(服务器路径)
* 2.用这个路径初始化字节流
*/
ServletContext application = ServletActionContext.getServletContext();
String realPath = application.getRealPath("/upload/" + fileName);
fileInputStream = new FileInputStream(realPath);
return "success";
}
public String getFileName() {
// 修改编码格式 方法是给struts提供的
// 当系统调用时 修改编码格式
try {
fileName = new String(fileName.getBytes(), "iso-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public InputStream getFileInputStream() {
return fileInputStream;
}
public void setFileInputStream(InputStream fileInputStream) {
this.fileInputStream = fileInputStream;
}
}
download.jsp
<form action="${pageContext.request.contextPath }/DownloadAction" method="post">
下载文件名:<input type="text" name="fileName">
<input type="submit" value="下载">
</form>
struts.xml
<struts>
<package name="UserAction" namespace="/" extends="struts-default">
<!-- 配置下载的Action类 -->
<action name="DownloadAction" class="com.lanou3g.DownloadAction" method="download">
<!-- 告诉浏览器我的返回结果 是个流类型 -->
<!--stream类型 是专门用来下载的-->
<result name="success" type="stream">
<!-- 相当于添加响应头 -->
<!-- 告诉浏览器 当前数据类型是下载 -->
<param name="contentType">application/octet-stream</param>
<!--动态获取下载的文件名 ognl表达式 可以动态获取文件名 相当于获取该对象的值-->
<param name="contentDisposition">attachment;filename=${fileName}</param>
<!--告诉struts 我们下载的输入流 对象名-->
<param name="inputName">fileInputStream</param>
</result>
</action>
</package>
</struts>