struts2的输入校验
1Action类中继承ActionSuport类(因为该类继承了validateable)覆盖其validate抽象方法在方法体中校验,并将其校验结果的信息(错误,提示信息)保存在fieldError中
- 执行流程:
jsp代码:
<h3>注册页面</h3>
<!--手动h获取错误信息,在root区域-->
<s:property value="fieldErrors.username[0]"/>
<s:fielderror fieldName="username"/>
<hr/>
<s:form namespace="/" action="check" method="post" theme="xhtml">
<s:textfield name="username" label="账号" />
<s:password name="password" label="密码"/>
<s:submit value="提交"/>
</s:form>
java代码:
package validate;
import com.opensymphony.xwork2.ActionSupport;
import lombok.Setter;
public class ValidateAction extends ActionSupport {
private static final long serialVersionUID = 1L;
@Setter
private String username;
@Setter
private String password;
public void validateExecute() {
if (username == null || !username.matches("^[a-zA-Z]\\w{5,15}$")) {
super.addFieldError("username", "账号第一个字必须为字母6~16位");
}
if (password == null || !password.matches("^[a-zA-Z]\\w{5,15}$")) {
super.addFieldError("password", "密码第一个字必须为字母6~16位");
}
System.out.println("执行校验");
}
public String execute() throws Exception {
System.out.println(username + "," + password);
System.out.println("ValidateAction1.execute()");
return SUCCESS;
}
}
xml配置Action:
<struts>
<package name="validatePkg" extends="struts-default" namespace="/">
<action name="check_*" class="validate.ValidateAction" method="{1}">
<!-- 校验失败的返回视图 -->
<result name="input">views/validate/login.jsp</result>
<!-- 校验成功的返回视图 -->
<result>views/validate/welcome.jsp</result>
</action>
</package>
</struts>
校验失败示意图:
从上面的流程可以看出调用Action的方法之前都会调用validate方法,但有些方法不需要校验:
解决方法:使用 @SkipValidation标签 贴在不需要校验的方法上.
大多数情况下的方法不需要校验,只有少数方法需要校验:
解决方法:在更改invalidate方法的方法名: 格式: invalidate+首字母大写的Action方法
struts2中默认会跳转到默认的input结果视图:
修改方法:@InputConfig(resultName = "结果视图名称")
struts2的文件上传
上传页面提示:
1):表单必须使用POST方式提交;
2):使用二进制编码:multipart/form-data;
3):<input type="file" name=""/>;
jsp:
<s:form namespace="/" action="upload" enctype="multipart/form-data" method="post">
<s:textfield name="username" label="昵称"/>
<s:file name="headImg" label="头像"/>
<s:submit value=" 提交 "/>
</s:form>
java代码:
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import lombok.Setter;
@SuppressWarnings("unused")
@Setter
public class UploadAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private File headImg;//上传文件
private String headImgFileName;//上传文件原始名称
private String headImgContentType;//上传文件的MIME类型
private String username;
public String execute() throws Exception {
//获取保存在本地的绝对路径
String url = ServletActionContext.getServletContext()
.getRealPath("/upload");
FileUtils.copyFile(headImg, new File(url, headImgFileName));
ActionContext.getContext().put("username", username);
ActionContext.getContext().put("headImg", "/upload/" + headImgFileName);
//用路径拷贝(但不会自动生成文件夹)
/*Files.copy(headImg.toPath(), Paths.get(url, headImgFileName));*/
return SUCCESS;
}
}
struts.xml配置:
<struts>
<!-- 加载上传失败的返回错误信息 -->
<constant name="struts.custom.i18n.resources" value="upload"></constant>
<!-- 单次上传请求文件大小,默认2M.此参数的值>="maximumSize的值 ,不然以此的大小为准-->
<constant name="struts.multipart.maxSize" value="2097152"></constant>
<package name="uploadPkg" extends="struts-default" namespace="/">
<interceptors>
<interceptor-stack name="myStack">
<!-- 重新注册拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 限制上传文件的拓展名 -->
<param name="allowedextensions">png,jpg,bmp,gif</param>
<!-- 限制上传文件的大小 默认2M(2097152字节) -->
<param name="maximumSize">2097152</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="upload" class="upload.UploadAction">
<interceptor-ref name="myStack"></interceptor-ref>
<result name="input">views\upload\upload.jsp</result>
<result>views\upload\welcome.jsp</result>
</action>
</package>
</struts>
在src-folder目录建立 上传文件覆盖默认错误信息,并在xml的 constant中配置(upload)文件名
<constant name="struts.custom.i18n.resources" value="upload"></constant>
以下是我自己配置的中文版错误提示信息:
Struts2的文件下载
Struts2提供了stream结果类型,该结果类型就是专门用于支持文件下载功能的。
jsp:
<a href="/download?filename=补.mp4">补.mp4</a>
<a href="/download?filename=misMVC.jar">misMVC.jar</a>
java:
package download;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import lombok.Getter;
public class DownloadAction extends ActionSupport {
private static final long serialVersionUID = 1L;
@Getter
private String filename;
public void setFilename(String filename) throws Exception {
//中文的文件名可能需要重新解码和编码
this.filename = filename;
}
//拦截器会调用改方法来获取被下载文件的输入流对象
public InputStream getTargetFile() throws Exception {
String url = ServletActionContext.getServletContext()
.getRealPath("/WEB-INF/download");
return new FileInputStream(new File(url, filename));
}
public String execute() throws Exception {
return SUCCESS;
}
}
xml:
<struts>
<package name="downloadPkg" extends="struts-default" namespace="/">
<action name="download" class="download.DownloadAction">
<result name="success" type="stream">
<!-- 让浏览器不要直接打开文件(默认值为inline),并设置建议下载名称 ,-->
<param name="contentDisposition">attachment;filename="${filename}"</param>
<!-- 指定文件输入流的入口,即输入流的名称,默认值是inputStream,配置自定义获取文件输入流名称 -->
<param name="inputName">targetFile</param>
</result>
</action>
</package>
</struts>