Strus2概览
来源:互联网 发布:编程cim是做什么的 编辑:程序博客网 时间:2024/06/05 15:44
目录
1.Struts2框架 2
1. Struts2与Servlet区别: 2
2.Struts2的使用步骤: 2
3.Struts2里用到的主要jar包: 3
4.Action类作用: 3
5.Struts2执行的流程:【重点】 3
2.action类实现接收和处理页面的信息 3
1. 将页面的input标签的name值设为action类的属性,然后生成该属性的getter、setter方法,然后就可直接引用属性得到页面的值 3
2. 声明一个JavaBean对象来当做action类里的属性来接收或处理页面传来的信息:对象.属性名,与之前一样,页面的name则也需写成:对象.属性名 4
3. jsp页面接收值 4
4.通配符 4
4.插多表 5
5. 查多表 5
6. 走完一个方法,如何走另一个方法【result的type属性】 5
7.关于struts配置里不能快捷生成的问题及其他 6
8.struts全局页面的配置及用法【配在package里,action外】 6
9.struts的访问页面的动态结果 7
10.通过Struts可以访问Sevlet API(主要是request,response,session,application) 7
11.xml配置文件里,action传值到另一个action里 7
12.Struts里的标签及ognl表达式 7
12.ognl表达式 8
13.用Struts标签实现 地区-街道 的二级联动[实在不理解用之前学的] 8
14. 用Struts验证,了解 8
15.配置文件里的开发模式 8
16. struts与jquery的异步操作【重点】 8
17.Struts拦截器 10
18.用Struts实现文件的上传与下载【重点】 11
1.文件上传的步骤: 11
2.文件下载的实现步骤: 12
19.Struts国际化 13
1.Struts2框架
是基于MVC的web应用框架的 ,作用于C层 (相当于以前的Servlet层)
1. Struts2与Servlet区别:
1. Struts是由servlet发展而来的
2. servlet里接收值返回信息到页面:用的是request 、session 。Struts2的action层通过属性或对象的形式来接收页面的值或返回信息到页面(在Struts2的Action层一般都是声明一个JavaBean对象来当做action里的属性来接收或处理信息的)
3. Struts2也有自己的一套体系标签
4. 它是通过配置文件的形式来跳转页面的 (便于咱们维护管理)
5. 与Servlet API松耦合(降低了耦合性), 便于测试维护
2.Struts2的使用步骤:
- 建一个Web Project工程,再把struts的相关jar放到web-inf/lib这个文件夹下去 :直接导Eclipse里包有点儿问题
- 创建并完成action类:两种方式
a) 实现Action接口
b) 继承ActionSupport类 【可以实现国际化化(各国都能看懂),数据校验等一些功能】
Sturts默认方法是execute(); 返回值类型是String类型。 - 在web.xml中配置struts2的过滤器
<filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>saveMovie.jsp</welcome-file></welcome-file-list>
4.创建配置文件struts.xml (页面进到action类,是由它引进去的 ;返回到哪个页面也是由它决定的) struts.xml:起到桥梁作用,它位于src文件目录下。在struts.xml中配置、及
package:是配置的空间
action:是决定走哪个action类,及其里面的哪个方法
result:决定走完action类里的某个方法后跳转到哪去,可以是跳到另一个action,也可以是一个jsp页面
<struts><!-- 配置空间名称: / 表示默认:即页面路径可不写空间名称 --><package name="default" namespace="/" extends="struts-default"> <!-- 创建action --> <action name="save" class="com.action.LibratyAaction" method="insertMovieMethod" ><!-- 页面的提交路径里的action的名字与name值相同;method是要进的action类里的方法 --> <result >/index.jsp</result> </action> </package><!-- 參數說明:package里的default是空間名稱,說明是默認的,只起标识作用,没其他用。package里的namespace="/"表示默認空間,頁面提交路徑不指定空間时就走这个默认的空间,如果namespace給定名字了,則路徑也要指定package里的extends是默認這麼寫的action里的save:是提交頁面里,路徑里指定的空間名称后的單詞。action里的class:是action层里的action類的所在路徑action里的method:指定的是要进的action类里的方法,如果不写,则走默认的execute方法result里的name是返action类的方法返回的字符串名,當返回的是系統常量,如success時,則可不用寫nameresult标签之間的頁面,是返回值后要跳轉的頁面 --><!-- 注意事項: 1.struts标签里可以有多个package,以namespace值區分 2.package標籤里可以配置多个action,但是ation里的name值不能一样,class可以一样 --><package name="packageName" namespace="/spaceName" extends="struts-default"> <action name="save" class="com.action.LibratyAaction"> <result name="flag">index.jsp</result> </action></package> </struts>
默认空间时jsp页面的form表单的路径写法:post提交不会有页面传的中文乱码问题
<form action="<%=basePath %>save" method="post">
指定空间时jsp页面的form表单的路径写法:
<form action="<%=basePath %>spaceName/save" method="post">
3.Struts2里用到的主要jar包:
struts2-core-2.3.4.1.jar Struts2的核心包
xwork-core-2.3.1.jar xwork的核心包
commons-io-2.0.1.jar 支持IO流读写的操作包
ognl-3.0.1.jar 支持struts2里的ognl表达式
…………………
4.Action类作用:
处理请求 、实现业务逻辑 、 返回result中决定的是哪个视图
5.Struts2执行的流程:【重点】
jsp页面(提交form表单,<a>
标签,js提交)—>Struts2的过滤器(配在web.xml里)—>符合条件的话(提交到struts.xml里的配置文件)–>根据配置文件找到相应的action类 –>进入相应的方法–>返回到struts.xml配置文件(根据方法的返回值来决定返回到哪个页面)
2.action类实现接收和处理页面的信息
1. 将页面的input标签的name值设为action类的属性,然后生成该属性的getter、setter方法,然后就可直接引用属性得到页面的值
接收页面的都是字符串形式,之所以能用double型的属性接收数字,是因为有强制转换;前提是要符合强转规则。
public class LibratyAaction extends ActionSupport{ private String bookName; //將jsp頁面里input标签里name值設為屬性 @Override//execute()是默认方法,返回值是字符串 public String execute() throws Exception { System.out.println(bookName);//打印接收到的頁面的值 return "flager";//返回的字符串flager用来标记在配置文件里走哪个页面 } //必须生成getter、setter方法,不然取不到值 public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; }}
2. 声明一个JavaBean对象来当做action类里的属性来接收或处理页面传来的信息:对象.属性名,与之前一样,页面的name则也需写成:对象.属性名
对象名是起的属性名
public class Movie2Action extends ActionSupport{ MovieService service=new MovieService(); //属性必须生成get set方法,这样才能存取值 private Movie movie;//struts2通过JavaBean对象来接收页面的值 private Seat seat; //座位号的javaBean private List<Movie> listMovies;//用来存放查回来的数据 private String msg; //存返回信消息 //插入 public String insertMovie(){ System.out.println(movie);//可用movie.getMname()取值 if(movie!=null&&movie.getMname()!=null&&!"".equals(movie.getMname())){ service.insertMovie(movie,seat); return this.SUCCESS;//相当于返回的字符串:success }else{ msg="请完善所有信息!!"; return this.ERROR; //相当于返回的字符串:error } } //查询所有 public String queryAllMovie(){ listMovies=service.queryAllMovie(); return "queryMovie"; } //生成的getter和setter方法 省略…… }
页面传值时,需将name属性的值也设成:对象名.属性名 的形式,如给影片名赋名:movie.mname
<tr> <td>影片名:</td> <td><input name="movie.mname"/></td> </tr>
复选框的值:可以自动接收拼接成逗号隔开的字符串,不需要我们自己拼接。我们只需要在action类里声明一个属性来接收拼接字符串,而在页面的复选框的name值需要全部写成那个属性名
3. jsp页面接收值
页面接收值也可用EL表达式:下面的employeeList是action类里存员工信息的属性名
<c:forEach var="e" items="${employeeList }" varStatus="status"> ${status.count }----${e.name }---${e.getSalary()}<br/> </c:forEach>
可以用:e.name,也可用e.getName();
这种接收值有个好处是,不用值回写,它是根据action类里的属性自动获取的
4.通配符
1.通配符:将配置文件里的action标签的name的值写成:名字+*
的形式。代表页面访问路径里的actionName里没有显示完的单词(这里写的是action类里的方法名),由于1代表取的第一个号的内容,这样就取到了传来的方法名。*
: 其实就代表了省略的内容,method里的数字相当于取省略的第几个内容
2.优点:访问路径需要走不同的方法时,可以只配置一个action
3.例子
<!-- 用通配符来访问struts method="{1}"的1取jsp页面url地址传过来的第1个*号的值 --><action name="movieAction*" class="com.zrgk.action.MovieAction" method="{1}"> <result>/index.jsp</result></action>
对应页面的访问路径:
<a href="<%=basePath%>addMovie/movieActionqueryMovie">查看影片信息</a>
4.多个通配符:可用下划线区分开,一般没有多个*的。一个时,最好也用“_”区分开
对应配置:这里走的是第二个方法
<action name="movieAction*_*" class="com.zrgk.action.MovieAction" method="{2}"> <result>/index.jsp</result></action>
对应访问路径:走的就是insertMovie方法
<a href="<%=basePath%>addMovie/movieActionqueryMovie_insertMovie">查看影片信息</a>
4.插多表
首先写另一张的Hibernate持久类,以及相关的配置信息,用以操作数据库
然后在action类里多写一个属性,用来存另一张表的信息;
再在dao层写一个类,用来写操作另一张表的方法
在action层多传一个表对应的javabean对象
public String insertMovie(){ System.out.println(movie); if(movie!=null&&movie.getMname()!=null&&!"".equals(movie.getMname())){ service.insertMovie(movie,seat); return this.SUCCESS; }else{ msg="请完善所有信息!!"; return this.ERROR; } }
再在service层调用dao层的两个类的插入方法。当然可以判一下空
MovieDao mdao=new MovieDao(); SeatDao sdao=new SeatDao(); public void insertMovie(Movie m,Seat se){ mdao.insertMovie(m); sdao.insertSeat(se);}
5. 查多表
多表联查
6. 走完一个方法,如何走另一个方法【result的type属性】
1.实现1:首先要将result里的type定义成redirectAction;然后将param的name属性设为actionName,用来指定进入到action里的哪个方法;再将另一个param标签的name属性的值设为namespace,用来指定进入到哪个空间
2.例子
<action name="movie2Action_*" class="com.zrgk.action.Movie2Action" method="{1}"> <result name="queryMovie">/queryMovie.jsp</result> <result name="error">/addMovie/saveMovie2.jsp</result> <result type="redirectAction"> <!-- 指定进入到哪个action 及方法--> <param name="actionName">movie2Action_queryAllMovie</param> <param name="namespace">/addMovie</param><!-- 指定进入到哪个空间 --> </result> </action>
3.实现2:将result的type属性设置为”redirectAction”;result标签之间是要跳去的action名与方法名。这种方式适用于要跳转去的另一个action与当前的在同一个空间里,所以不用指定namespace
<action name="movie2Action_*" class="com.zrgk.action.Movie2Action" method="{1}"> <result type="redirectAction">movie2Action_queryAllMovie</result></action>
注意的是:如果跳到的另一个action不是通配符的形式,则不需要指定方法
4.result的属性:
1). redirectAction转向跳入另一个action,可接收一个参数
2 ) . redirect重定向,跳入页面。 不能带参数到页面
3).dispatcher转发到另一页面。可带参数到页面
4).stream表示处理流相关的信息(文件的上传与下载)
5).chain:表示跳转到另一个action和对应的方法,可接收到前一个action里的所有值
7.关于struts配置里不能快捷生成的问题及其他
首先,在src目录下放入 文件,
然后,将所有配置文件的头部分(struts标签以上)改成:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd">
不解决时,当有网时,也可以快捷生成
1. Tomcat要放在英文目录下,不然在Struts里配置几个配置文件时,运行就会报错
2. form表单要post提交,不然提交中文会乱码
3. struts有多个配置文件时,先走的是总配置文件,然后走里面导入的配置文件;至于要走哪一个,根据页面的路径里的空间名称与action名字查找,所以,几个分配置文件里不能有相同的空间名。也可这样解释,所有分配置的代码导入到总配置里后,形成了一个配置文件,那么,空间名称肯定不能重复啦。
4. 有时候,我们改了工程名,再次运行时会出问题,是因为改名后,tomcat里发布的还是原来的工程。我们可以鼠标右击改名后的工程——>属性——>输入Web搜索——>如果运行不成功,可发现web Context-root里的工程名还是改名之前的名字,我们可以在这里改成我们要改的名字——>OK
8.struts全局页面的配置及用法【配在package里,action外】
<!-- 配置全局转向页面 --><global-results><!-- 里面可配置多个result --> <result name="errorPage">/error/errorPage.jsp</result></global-results><!-- struts处理异常信息 --><!-- result的值errorPage是要跳转到的全局页面里的name的值,exception的值是异常类全称 --><global-exception-mappings><!-- 里面可配置多个 --> <exception-mapping result="errorPage" exception="java.lang.NullPointerException"></exception-mapping></global-exception-mappings>
exception=”javar.lang.OutOfMemoryError” 是内存溢出错误
9.struts的访问页面的动态结果:最好不用,项目完成后不能修改跳转路径
优点:要访问哪个页面,直接在action类里给出地址,不用再去配置里做更改了
缺点:在生成.class文件后,不能更改跳转页面了。最好还是跳转路径写在配置文件里,因为配置文件是可更改的。
1. 在action类里声明一个存jsp页面路径的属性jspPath,然后生成getter、setter方法,可写个默认页面
private String jspPath=”/index.jsp”;
2. action类里的方法里给jspPath属性赋值:jsp页面路径+jsp文件名全称,包括后缀.jsp
jspPath=”/addMovie/saveMovie2.jsp”;
3.在配置里的result里获取jspPath属性:${jspPath}
<action name="movie2Action_*" class="com.zrgk.action.Movie2Action" method="{1}"> <result>${jspPath}</result></action>
10.通过Struts可以访问Sevlet API(得到request,response,session,application)
在action里的方法里面可使用Servlet里的一些作用域,跟之前在serlvet里使用一样:
//1.从容器里获取request
HttpServletRequest request=ServletActionContext.getRequest();
//2.得到session
HttpSession session= ServletActionContext.getRequest().getSession();
//3.得到response
HttpServletResponse response=ServletActionContext.getResponse();
//4.得到application:作用域为整个工程 Map<String,Object>
application=ServletActionContext.getContext().getApplication();
存值:application.put(“myinfo”, “this is my information”);
在jsp页面取值:也可有EL表达式:${key},有了值后,关闭浏览器再打开,还是有值,
11.xml配置文件里,action传值到另一个action里
1.action跳action传的写法用?mag=值 这样追加值再到另一个action里接收 (这个类拟于get提交的方式,应避免传中文)
<result type="redirectAction">movie2Action_queryAllMovie?msg=${msg}</result>
该方式不能传中文,只适合传Id这种整形或是字母的,类似get提交,好像也不能传多个值
2.一种更好的传值方式
将result的type属性的值改为:chain
<result type="chain">movie2Action_queryAllMovie</result>
能传中文,能将上一个action里的所有属性的值都传给下一个action 。如果一个参数都不想传,最好不用这种方式,因为这种方式是将所有的都要传过去,这里做的准备工作比较多,所以这时性能会有些不好。
12.Struts里的标签及ognl表达式
使用struts标签要先导包:<%@ taglib uri=”/struts-tags” prefix=”s”%>
使用ajax标签要导另一个包:<%@taglib uri=”/struts-dojo-tags” prefix=”sx”%>
详细见:Struts2标签
1. 标签的分类:
1) 通用标签【默认前缀s】
a) 数据标签
b) 控制标签
2) UI标签【默认前缀s】
3) ajax标签【默认前缀sx】
2. 数据标签:提供对各种数据的访问
输出相关属性的值
在页面上生成一个链接,单击可以输出容器的一些信息(可能包含错误信息)
格式化输出一个日期
生成一个url地址
生成html里的标签
为其它标签添加参数信息
把其它页面包含到当前页面上
3.控制标签:用来完成对分支流程的控制 相当java中的 if eseif else等
判断的标签
循环标签
4.UI标签:用来生成UI界面元素表单这些信息
对应的是html里表单标签
对应的文本框的标签
提交的标签
下拉框的标签
生成一个二级联动的下拉框
5.ajax标签
<sx:datetimepicker>生成一个日历控件
12.ognl表达式
ognl表达式简介
13.用Struts标签实现 地区-街道 的二级联动
参见代码。
14. 用Struts验证,了解
好处:当浏览器不支持js时可用它
1. 在action层里写一个校验器文件:UserAction-registerAction-validation.xml
命名规则:action类名-action名字- validation.xml
2.所以该验证是要走后台的,后台通过后才走action
具体参见代码
15.配置文件里的开发模式
<!-- 设置Struts简单的主题模式 --><constant name="struts.ui.theme" value="simple"/><!-- 设置struts为开发模式:修改该struts.xml文件后,不用重启服务,也可生效 --><constant name="struts.devMode" value="true" /><!-- true表示启用开发模式 -->
16. struts与jquery的异步操作【重点】
struts与jquery的异步操作步骤:
1.写action里的异步方法
public class TestAction extends ActionSupport { private String username;//{"username":"salmon"} private String msg;// {"msg":"1"} public String execute(){ if(username!=null&&username!=""){ if("picluo".equals(username)){ this.setMsg("重名了"); }else{ this.setMsg("可用"); } }else{ this.setMsg("用户名不能为空"); } return this.SUCCESS; } /*以流的形式实现异步 public String execute() throws Exception{ HttpServletResponse response=ServletActionContext.getResponse(); response.setContentType("text/html;charset=utf-8"); PrintWriter out=response.getWriter(); if("picluo".equals(username)){ out.print("true"); }else{ out.print("false"); } out.close(); return null; }*/ //生成的getter、setter方法,此处省略…… }
2.配置异步的返回信息
<!--引用的json一个文件--> <package name="ajax" namespace="/" extends="json-default"> <action name="test" class="com.salmon.action.TestAction"> <result type="json">index.jsp</result><!--指定返回类型的json格式--> </action> <!-- <action name="test" class="com.salmon.action.TestAction"> 以流的形式实现异步的配置 </action> --> </package>
也可以不引有json文件,我们在action里直接return null;在方法里面将数据写入流里:
如:PrintWriter out=response.getWriter();
out.print(sb.toString());//把字符串写入流里面【重点】
3.在jsp页面导入jquery的js文件
<script type="text/javascript" src="<%=basePath%>js/jquery-1.8.2.js"></script>
或者是:
<script type="text/javascript" src="<%=basePath %>js/jquery-2.0.2.js"></script>
4. 写jsp页面及js的异步信息【4个参数】
<script type="text/javascript" src="<%=basePath %>js/jquery-2.0.2.js"></script> <script type="text/javascript"> function checkName() { var usernameValue = document.getElementById("userName").value; var today = new Date(); $.ajax({ //后面跟一个时间的参数是为了防止有时候不提交的问题【冲破缓存,也可跟个随机数】 url:"test?time="+today.getTime(),//test是配置里的action名字 type:"post",//提交方式 data:"username="+usernameValue,//username是action类里的属性 success:function(data){//回调函数:返回的是json串,属性都封装在里面 var username = data.username;//得到actoin类里的属性值 $("#ms").html(data.msg); //将提示结果放进span标签里,span标签不是表文件框,所以没有value,只能用html接收值 } }); } function clears() { document.getElementById("userName").value=""; $("#ms").html("莫乱输哈"); } </script> </head> <body> 用户名: <input type="text" name="userName" id="userName" onblur="checkName();" value="请输入用户名" onfocus="clears();"> <span id="ms" name="ms"></span> </body>
17.Struts拦截器
1.工作流程:
struts.xml——>拦截器1——>拦截2——>…拦截器n——>调用Action里的method——>再返回到拦截器n——>…拦截器2——>拦截器1——>struts.xml的
2.实现拦截器的步骤:
a.写一个普通的类,通过实现Interceptor接口或继承AbstractInterceptor抽象类,或者继承MethodFilterInterceptor类来变成一个拦截器的类,即拦截器。MethodeFilterInterceptor类,在只拦截部分的action里的方法里用
b.在struts.xml中定义拦截器(将拦截器配置到struts容器里去)
<package name="addMovie" namespace="/addMovie" extends="struts-default"> <interceptors> <!-- 配置写的拦截器类: 这里面可以配置多个拦截器类 --> <interceptor name="myInterf" class="com.zrgk.interf.MyInterceptor"></interceptor> </interceptors> <action name="movie2Action_*" class="com.zrgk.action.Movie2Action" method="{1}"> <!-- 引用拦截器 --> <interceptor-ref name="myInterf"></interceptor-ref><interceptor-ref name="defaultStack"/><!—自带拦截器 --> <result>/index.jsp</result> </action></package>
c.在中引用配置的拦截器
3.Struts自带大量的拦截器,它们定义在struts-default.xml文件中
自带的拦截器实现了获取更多的参数信息,为action注入session 、异常处理、 国际化,数据验证等
4.常用 的自带拦截器的一些参数信息:
params: 负责将请求参数设置到action类中对应的属性中去
SevletConfig :将源于ServletAPI的各种对象注入到Action中去????不太理解????
validation: 调用验证框架进行的数据校验
exception : 进行异常处理 ,将异常映射为结果
i18n : 提供国际化支持
5.把一组拦截器定义在一起叫做 拦截器栈
struts2的默认拦截器栈是defaultStack ,它里面会有多个拦截器。
18.用Struts实现文件的上传与下载【重点】
1.文件上传的步骤:
1) 在jsp页面写上传文件的标签<input name="movieFile" type="file"/>
2) 给form标签加上传输文件的编码方式:enctype=”multipart/form-data”
<form action="<%=basePath %>addMovie/movie2Action_insertMovie" method="post" enctype="multipart/form-data">
enctype默认值认为application/x-www-form-urlencoded,还有一个选项是:text/plain
3) 给action起一个存文件类型的属性名, 如果要用到文件名则这样起名:文件类型的属性别名+FileName (区分大小写问题) 如果想得到上传的文件后缀则:文件类型的属性别名+ContentType
public class Movie2Action extends ActionSupport{//1.声明接收文件的属性 private File movieFile; //2.声明接收文件名的属性,命名规则:File的别名(上一步声明的接收文件的属性名)+FileName, struts2会自动把上传的带后缀的文件名给这个属性private String movieFileFileName;//3.声时接收文件类型的属性,命名规则:File的别名+ContentType,自动把文件类型给这个属性。这里所说的类型是指文本类型还是图片类型 private String movieFileContentType; public String insertMovie(){ try{ //设置新文件的目录+文件名 //ServletActionContext.getServletContext().getRealPath("/upload/")动态获取upload的位置 String newPath=ServletActionContext.getServletContext().getRealPath("upload/"+movieFileFileName); //得到新的文件路径,用于存上传的文件。文件名要写到getRealPath的括号里 FileInputStream fis=new FileInputStream(movieFile);//把旧文件读进内存 FileOutputStream fos=new FileOutputStream(new File(newPath));//写到新文件的流 IOUtils.copy(fis, fos);//把旧文件复制到新文件下去【这可比以前简单多了,一句搞定】 fos.flush();//不flush就不能真正地从内存中输出到文件里去 fos.close();//一定要关闭 fis.close(); return this.SUCCESS; }catch(Exception e){ return "errorPage"; } } //生成的getter、setter方法,此处省略… }
4) 配置struts.xml文件
<action name="movie2Action_*" class="com.zrgk.action.Movie2Action" method="{1}"> <!—引用上传文件的拦截器 --> <interceptor-ref name="fileUpload"><!-- 设置上传的文件大小问题 单位:字节 --> <param name="maximumSize">10000000</param> <!-- 也可以使用allowedTypes来控制上传的文件类型,以下是允许传的文件格式 --> <param name="allowedExtensions">jpg,jpeg,gif,png,txt,sql</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> </action>
由于上付文件的拦截器是系统的,所以引用时,里面的name值都是来源于系统,所以都不能写错了
2.文件下载的实现步骤:
1.写一个下载的action类,里面写一个存文件名的属性并生成get、set方法,写一个action默认走的方法execute, 然后写一个走完execute方法返回后在result里调的getInputStream()方法(把服务器的文件读到输入流里去)。getInputStream方法一定是struts.xml里的inputStream对应的getter方法
public class DownloadAction extends ActionSupport{ private String fileName;//传过来的要下载的文件名 /**读取文件的流对象返回,Web服务器会读取流对象中的数据并封装到response中,然后发送到客户端 */ public InputStream getInputStream() throws FileNotFoundException, UnsupportedEncodingException{ System.out.println("走完默认方法返回后,在result里才调用的这个方法"); InputStream is = null; //把URL路径转化为服务器的本地路径 String realPath = ServletActionContext.getServletContext().getRealPath("/upload/"+this.fileName); is = new FileInputStream(realPath); return is;//返回流 } //默认的方法 public String execute(){ System.out.println("因配置里没有写方法,所以走这个默认方法:下载的业务方法"); return this.SUCCESS; } //存文件名的getter方法,里面解决了中文乱码问题 public String getFileName() throws UnsupportedEncodingException { //解决中文文件名的乱码问题 return java.net.URLEncoder.encode(fileName, "UTF-8");//该编码方式在IE6下可能有该问题:文件名长度不能超过16个字符 //return new String(this.fileName.getBytes("UTF-8"),"ISO-8859-1");//该编码方式可兼容IE6,但GBK不利于实现国际化 } //存文件名的属性的setter方法 public void setFileName(String fileName) { this.fileName = fileName; } }
2.在struts.xml配置下载文件的一些信息
将result的属性改为stream
在result里参数调用getInputStream方法得到流???这儿没有实现,老报错?
指定浏览器弹出窗口,让用户选择保存位置;并得到文件名
指定缓冲区的大小
<package name="download" namespace="/download" extends="struts-default"><action name="downloadAction" class="com.zrgk.action.DownloadAction"> <result name="success" type="stream"> <!--文件对应的流对象 调用 getInputStream()方法 , 之所以能调,是因为inputStream相当于action类里的属性,没写出来 所以action里的getInputStream()方法相当于该属性生成的getter方法 所以,名字也得对应好了。这里就相当于用属性用了方法 --> <param name="inputName">inputStream</param> <!-- attachment指定浏览器弹出窗口,让用户选择保存位置的属性设置 --> <param name="contentDisposition">attachment;filename="${fileName}"</param><!--发送给客户端的文件名,需要注意中文乱码问题 --> <!--文件类型,application/octet-stream表明不限制类型 --> <param name="contentType">application/octet-stream</param> <param name="bufferSize">1024</param><!--缓冲区大小 --> </result> </action></package>
3.在页面用超链接调用下载的action(注意的是,要传一个服务器上存在的文件名)
<form action="<%=basePath %>download/downloadAction" method="post"> <input type="hidden" name="fileName" value="${movieFileFileName}"> <input type="submit" value="点击下载"></form>
注意的是,提交路径或是用a标签的路径里,都不能传参,因为中文会乱码。可用上面的隐藏域传过去
19.Struts国际化
国际化就是使页面根据不同的国家选择不同的语言展示方式,实现步骤如下:
1.在src下加载国际化资源配置文件,一个国家对应一个:下面是美国与中国的两种语言
配置文件名是的第一个单词可变,后面的是根据不同国家,起的固定格式,
美式英语的配置里内容为:
title_label = register
user_name = USERNAME
password = PASSWORD
age_lable = AGE
submit =SUBMIT
中文里的配置内容为:
title_label = \u6CE8\u518C
user_name = \u7528\u6237\u540D
password = \u5BC6\u7801
age_lable = \u5E74\u9F84
submit = \u63D0\u4EA4
增加字段时,先选择properties窗口,然后点添加。添加后就会出现如上的格式
2.写国际化的action类,虽没内容,但也要写:
public class I18nAction extends ActionSupport { public String execute(){ //这里什么也没写,但必须写这个类和这个默认方法 return this.SUCCESS; }}
3.配置struts.xml文件
<struts> <!-- 后缀修改: 代表访问的action要加上.action的后缀 --><constant name="struts.action.extension" value="action"/> <!-- 开发模式:设为开发模式后,若配置发现改变不重新启动也可生效 --> <constant name="struts.devMode" value="true" /> <!-- 国际化资源文件: lanaguage表示引用的src下以这个单词开头的.properties文件--> <constant name="struts.custom.i18n.resources" value="lanaguage"></constant> <package name="test" namespace="/" extends="struts-default"> <!-- i18n的action类的位置路径,虽然里面什么也没有,但必须写 --> <action name="i18n" class="com.zrgk.action.I18nAction" > <result name="success">index.jsp</result> </action> </package></struts>
4.在页面引用国际化语言
<script type="text/javascript"> function i18n(local){ location.href="i18n.action?request_locale="+local; //配置里设了修改后缀为要加.action所以这里要加 }</script> </head> <body> <!--括号里传的是指定的语言 --> <a href="javascript:i18n('zh_CN')">中文</a> <a href="javascript:i18n('en_US')">English</a> <hr/> <s:form action="i18n.action" method="post"> <!-- key里的值是对应的国际化资源文件里的key --> <s:textfield key="user_name" name="username"></s:textfield> <s:password key="password" name="userps"></s:password> <s:textfield key="age_lable" name="age"></s:textfield> <s:submit key="submit"></s:submit> </s:form> </body>
5.实现效果如下:
6.可通过浏览器的工具里的Internet选项进行设置,可实现打开浏览器时默认以哪种语言打开可添加其他语言
- Strus2概览
- strus2注解
- strus2注解
- strus2注解
- 概览
- Strus2的应用
- 解决strus2中文乱码
- 解决strus2中文乱码
- strus2 配置详解
- Strus2的处理流程
- Strus2上传文件大小
- strus2文件上传
- Strus2学习笔记-02
- Mybatis+strus2+spring 整合
- strus2超简单实例
- Strus2与SpringMVC 对比
- strus2标签大全
- Strus2类型转换器心得
- java8 JDK1.8 API 中文 翻译版 java帮助文档
- 变量作用范围级别
- 前缀、中缀、后缀表达式
- Windows的APC机制
- extundelete应用实战
- Strus2概览
- Apache与Tomcat有什么关系和区别
- 2017/9/3 训练总结
- 基于Qt的中国男足国家队“世亚预”小组赛出线分析
- 经验模态分解
- Python学习第一课
- nodejs爬虫参考
- python maximum recursion depth exceeded解决方式
- 倒水(rms2017模拟2-1)* 【推理】