版本不同,和书上的使用有些不一样,增加了一些细节。
Action
DefaultAction.java
这是一个指向需要切换国际化的页面自己的Action,在国际化时,如果超链接是向本页面传递request_locale
参数,这个参数没有经过后台服务器修改Session,就不能完成国际化,所以需要这样一个Action。
package myAction;
//回到default页面的Action,可以用来做国际化切换时提交到的后台
//仅仅用来将request_locale参数传到session里
public class DefaultAction {
public String execute() {
return "success";
}
}
MainAction.java
这是登录时经过的Action,在它之前配置了一个拦截器,用来禁用以root身份登录,但在这个Action的实现中看不出来。
package myAction;
import myBean.User;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class MainAction extends ActionSupport {
// 组合一个User对象以做域模型注入
User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
UploadAction.java
文件上传功能的实现Action,需要组合一个File字段使用属性注入,一个String字段在File字段后加FileName
,也将被属性注入,为上传时的文件名。
package myAction;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
//上传文件的Action
@SuppressWarnings("serial")
public class UploadAction extends ActionSupport {
private List<File> upld;// 上传的文件,需要符合属性注入
private List<String> upldFileName;// 上传的文件名,需要是上面那个属性后面加个"FileName"
@Override
public String execute() throws Exception {
if (upld == null)
return ERROR;
// 多文件上传相当于对List中的所有文件做单文件上传
for (int i = 0; i < upld.size(); i++) {
// 根据上传的文件得到输入流
InputStream is = new FileInputStream(this.upld.get(i));
// 指定输出流在服务器上的地址,提前建立该目录
OutputStream os = new FileOutputStream("e:\\upload\\"
+ this.upldFileName.get(i));
// 用来存内容的字节数组
byte[] buffer = new byte[1024];
int count = 0;// 将byte读成int
while ((count = is.read(buffer)) > 0) {
// 写入
os.write(buffer, 0, count);
}
// 将流关闭
os.close();
is.close();
}
return SUCCESS;
}
// 多文件上传时相应的getter和setter也要变成list类的
public List<File> getUpld() {
return upld;
}
public void setUpld(List<File> upld) {
this.upld = upld;
}
public List<String> getUpldFileName() {
return upldFileName;
}
public void setUpldFileName(List<String> upldFileName) {
this.upldFileName = upldFileName;
}
}
Struts2配置文件
struts.properties
有关这些功能需要做一些配置,特别是国际化需要配置国际化资源文件名,文件上传应当重写文件缓存位置。
#激活开发模式,提供更全面的调试功能
struts.devMode=true
#开启DMI动态方法调用
struts.enable.DynamicMethodInvocation=true
#是否自动重新加载本地的国际化资源文件,开发阶段应设为true
struts.i18n.reload=true
#重设默认主题
struts.ui.theme=simple
#重设默认国际化语言
struts.locale=zh_CN
struts.i18n.encoding=utf-8
#国际化资源文件名
struts.i18n.resource=myRsrc
#设置浏览器是否缓存静态内容,开发阶段应设为false
struts.serve.static.browserCache=false
#指定上传文件的临时存放位置,提前建立该目录
struts.multipart.saveDir=E:/mytemp
struts.url.includeParams=none
#激活重新载入xml配置文件的功能
struts.configuration.xml.reload=true
#配置服务器的端口
struts2.url.http.port=8080
#把Struts2的类生成交给Spring完成
#struts.objectFactory=spring
struts.xml
系统默认的拦截器栈defaultStack
在配置了拦截器的包下的Action中都应使用,否则访问时会找不到页面。
<?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>
<!-- 默认包,lzh命名空间,继承struts-default以使用Struts2提供的默认拦截器 -->
<package name="default" extends="struts-default" namespace="/lzh">
<!-- 配置拦截器 -->
<interceptors>
<!-- 拦截器名,实现类 -->
<interceptor name="mainIntrcptr" class="myInterceptor.MainInterceptor"/>
</interceptors>
<default-interceptor-ref name=""/>
<!-- 用户登录时提交到的Action -->
<action name="main" class="myAction.MainAction">
<!-- 这里的/将从默认命名空间开始 -->
<result name="success">/main.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/default.jsp</result>
<!-- 使用系统默认拦截器栈 -->
<interceptor-ref name="defaultStack"/>
<!-- 配置自定的mainIntrcptr拦截器 -->
<interceptor-ref name="mainIntrcptr"/>
</action>
<!-- 回到default.jsp的Action -->
<action name="dflt" class="myAction.DefaultAction">
<result name="success">/default.jsp</result>
<!-- 只要配置了拦截器,在默认包下的Action就要使用系统的默认拦截器栈 -->
<interceptor-ref name="defaultStack"/>
</action>
<!-- 用来提交文件的Action -->
<action name="upload" class="myAction.UploadAction">
<result name="success">/sccss.jsp</result>
<result name="error">/error.jsp</result>
<!-- 只要配置了拦截器,在默认包下的Action就要使用系统的默认拦截器栈 -->
<interceptor-ref name="defaultStack"/>
</action>
</package>
</struts>
国际化资源文件
myRsrc_en_US.properties
配置使用美式英语时的文字。
username=UserName
password=Password
login=Login
title1=Interceptor and i18n international demonstration.
title2=When you log in using 'root', you are intercepted and returned to this page.
title3=Multi-file upload demo.
sbmt=Submit
here=Click here to upload
myRsrc_zh_CN.properties
配置使用大陆中文时的文字。不需要使用书上的繁琐方式,直接在Eclipse中将该文件编码改成ISO-8859-1
,然后直接打中文就会自动转码成Latin-1
,将鼠标放上去时可以显示对应的中文。
username=\u7528\u6237\u540D
password=\u5BC6 \u7801
login=\u767B\u5F55
title1=\u62E6\u622A\u5668+i18n\u56FD\u9645\u5316\u7684\u6F14\u793A
title2=\u4F7F\u7528root\u5C1D\u8BD5\u767B\u5165\u65F6\u4F1A\u88AB\u62E6\u622A\u56DE\u5230\u8BE5\u754C\u9762
title3=\u591A\u6587\u4EF6\u4E0A\u4F20\u7684\u6F14\u793A
sbmt=\u63D0\u4EA4
here=\u70B9\u51FB\u8FD9\u91CC\u4E0A\u4F20
JSP页面
default.jsp
按照TGUIDE规范书写是有益的,超链接使用绝对路径可以防止URL越点越长。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@taglib prefix="sx" uri="/struts-dojo-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>登录页面</title>
</head>
<body>
<%-- 切换语言时去申请一个直接回到本页面的Action,以将国际化参数传入Session中 --%>
<a href="/TT/lzh/dflt.action?request_locale=en_US">English</a>
<a href="/TT/lzh/dflt.action?request_locale=zh_CN">中文</a>
<%-- 在需要国际化的范围内指定国际化配置文件名前缀 --%>
<s:i18n name="myRsrc">
<h1>
<%-- 使用s:text的name属性会去查找本语言国际化文件的key取出value --%>
<s:text name="title1" />
</h1>
<h2>
<s:text name="title2" />
</h2>
<%-- 登录的表单 --%>
<s:form action="/lzh/main" method="post">
<s:text name="username" />:<s:textfield name="user.username" size="20" />
<br>
<br>
<s:text name="password" />:<s:password name="user.password" size="20" />
<s:submit value="%{getText('login')}" />
</s:form>
<br>
<br>
<br>
<h1>
<s:text name="title3" />
</h1>
<%-- 文件上传的表单,multipart/form-data指定以二进制流方式处理表单数据 --%>
<s:form action="/lzh/upload" method="post" enctype="multipart/form-data">
<!-- 这里使用域模型注入 -->
<s:file name="upld" title="%{getText('here')}"/>
<br>
<s:file name="upld" title="%{getText('here')}"/>
<br>
<s:file name="upld" title="%{getText('here')}"/>
<br><br>
<s:submit value="%{getText('sbmt')}" />
</s:form>
</s:i18n>
</body>
</html>
main.jsp
<%@ 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>登录成功</title>
</head>
<body>
<h1>登录成功页面</h1>
</body>
</html>
error.jsp
<%@ 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>出错页面</title>
</head>
<body>
<h1>操作失败,点击<a href="../default.jsp">这里</a>返回</h1>
</body>
</html>
sccss.jsp
<%@ 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>提交成功</title>
</head>
<body>
<h1>文件已经成功上传到服务器!</h1>
</body>
</html>
运行结果
文件上传的临时目录和最终目录都是提前建立好的。
点击切换成英文:
上传文件:
查看一下: