Struts2.1笔记
来源:互联网 发布:recuva数据恢复 编辑:程序博客网 时间:2024/06/03 14:31
最近在学习Struts2,正好看见这篇文章,果断转了!!很不错,帮助很大啊!
原文:http://blog.csdn.net/liupeng_family/article/details/18964935
Struts2.1官方文档:1.set标签处value的String改为object2.struts2标签的type为String表示字符串,为Object表示Ognl表达式一:Myeclipse的简单操作1.将类进行源码展示:右击Jar包->Properties->Java Source Attachment->F:/JAR_Total/Struts/struts2.x/struts-2.1.8.1/src/core/src/main/java2.文档的展示:右击Jar包->Properties->JavaDoc Loction->file:/F:/JAR_Total/Struts/struts2.x/struts-2.1.8.1/docs/struts2-core/apidocs/之后出现新类的时候直接按F1就可以在Myeclipse中查看文档3.Struts.xml不自动提示a)window – preferences – 搜索 catalog b)选择key type为URIc)key: http://struts.apache.org/dtds/struts-2.0.dtdd)location: 对应的dtd文件,位于struts-core包中,解压开,指定相应位置,如:D:\share\0750_Struts2.1.6\soft\struts-2.1.6\lib\struts2-core-2.1.6\struts-2.0.dtd4.右击项目->java->compliance->compiler compliance level->1.65.常量的配置保存在struts2-core-2.1.8.1.jar->org.apache.struts2->default.properties6.<constant name="struts.devMode" value="true" />:此时表示正处于开发模式,可以不用重新启动服务器而直接访问修改后的内容一.1:Struts2流程Struts2多实例,多线程Servlet单实例,多线程 二:NameSpacea)namespace决定了action 的访问路径,默认为“”,可以接收所有路径的action,例如http://localhost:8080/Test/asdfasdfas/sdgsdg/sdfsdfsd/index.actionb)当将现有的项目拷贝出来一份以后,一定要记得,右击项目->Properties->Myeclipse->Web,将Web Context-root修改掉。三:Actiona) 具体视图的返回可以由用户自己定义的Action来决定b) 具体的手段是根据返回的字符串找到对应的配置项,来决定试图的内容c) 具体Action的实现可以是一个普通的Java类,里面有public String execute()方法即可d)修改默认编码:windows->preference->JSPe)Struts2的Action在每次访问时必定会new一个,而Struts1的Action在每次访问的时候可能只有new了一个f)实现Action的三种方法:1.直接写类名称+execute()方法2.继承自ActionSupport类+execute()方法3.实现自Action接口+execute()方法四:Path_路径问题a)Struts2中的路径问题是根据Action的路径而不是Jsp的路径来确定,所以尽量不要使用相对路径<br>虽然可以用Redirect方式解决,但是Redirect方式并非必要的。<br>解决方法非常简单,统一使用绝对路径(在Jsp中使用request.getContextRoot方式来拿到webapp的路径,或者使用Myeclipse自己写的) 五:ActionMethod1.Action执行的时候不一定要执行execute方法,可以在配置文件中配置Action的时候用method=来制定执行哪个方法 ,也可以在在url地址中动态制定(动态方法调用DMI),还可以使用通配符来进行操作(user是命名空间,userAdd是Actino的名称)http://localhost:8080/Struts2_0400_Path_ActionMethod/user/userAdd(action!method.action,user是Action的名称,userAdd是方法名)http://localhost:8080/Struts2_0400_Path_ActionMethod/user!userAdd六:ActionWildcard(通配符)使用通配符,将配置降到最低,不过,一定要遵循“约定优于配置”原则 <action name="*_*" class="com.bjsxt.struts2.action.{1}Action"> <result>/{1}_{2}_success.jsp</result> </action>七:接收参数的方式用Action的属性接收参数<a href="<%=basePath%>user/user!add?name=lp&age=20">用Action的参数接收属性</a>private String nameString;private int age;public void setName(String name){(name的名称与参数名称一致就行了)this.nameString = name;}用DomainModel接收参数(SSI框架中可以省去user.name中的user)private User user;(加入setter()和getter()方法)public String show(){//User user = getUser();System.out.println("取得名称:"+ user.getName());System.out.println("取得年龄:"+ user.getAge());return "show";}<a href="user/user!show?user.name=a&user.age=8">添加用户</a>用ModelDriven接收参数(SSI中继承自BaseActionSupport使用此种方法)<a href="user/user!add?name=a&age=8">添加用户</a>//实现ModelDriven接口(记住使用泛型,否则需要类型强制转换)public class UserAction extends ActionSupport implements ModelDriven<User>{//此处必须实例化对象,而不是使用setter和getter方法private User user = new User();@Overridepublic User getModel() { return user;}public String show(){User model = getModel();System.out.println("取得名称:"+model.getName());System.out.println("取得年龄:"+model.getAge());return "show";}八:简单数据验证 简单数据验证1Actionif(name == null || !name.equals("admin")){this.addFieldError("name", "name is error");return ERROR;}JSP,<s:fielderror fieldName="name" theme="simple"/><br /><s:property value="errors.name[0]"/> 专门取得valueStack和Stack中的Context中的值<s:debug></s:debug>Value Stack ContentsObjectProperty NameProperty Valuecom.model.Testname刘鹏age20com.demo.TestActiontextsnullmodelcom.model.Test@59c8b5actionErrors[]errors{name=[name is error!]}fieldErrors{name=[name is error!]}errorMessages[]localezh_CNactionMessages[]com.opensymphony.xwork2.DefaultTextProvidertextsnull九:访问web元素(详见另外一份文档)十:模块包含(IncludeModlus)Struts.xml:<struts><include file=”login.xml”></struts>Login.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="login" extends="struts-default" namespace="/login"> <action name="login" class="com.bjsxt.struts2.user.action.LoginAction"> <result>/user_login_success.jsp</result> </action> </package></struts>十一:默认Action<struts> <package name="default" extends="struts-default" namespace="/"> <default-action-ref name="index"></default-action-ref><action name="index" class="com.bjsxt.struts2.user.action.LoginAction"> <result>/user_login_success.jsp</result> </action> </package> </struts>十二:默认Result_Type1.Dispatcher //显示action地址2.Redirect //显示jsp地址3.Chain 4.redirectAction 5.freemarker6.httpheader7.stream8.velocity9.xslt10.plaintext11.tils<struts><package name="resultTypes" extends="struts-default" namespace="/r"> <action name="r1" class="com.bjsxt.struts2.user.action.LoginAction"><!-- 服务器端跳转,不能跳转到Action,只能跳转到试图 --><result type="dispatcher">/user_login_success.jsp</result></action><action name="r2" class="com.bjsxt.struts2.user.action.LoginAction"><!-- 客户端跳转,不能跳转到Action,只能跳转到试图 --><result type="redirect">/user_login_success.jsp</result></action> <action name="r3" class="com.bjsxt.struts2.user.action.LoginAction"><!-- 使用forward(服务器端跳转)的方式访问Action --><result type="chain"><param name="actionName">a</param><param name="namespace">/a</param></result><!-- aaa/r1 --></action><action name="r4" class="com.bjsxt.struts2.user.action.LoginAction"><!-- 客户端跳转,跳转到Action --><result type="redirectAction">r2</result></action></package> </struts>十三: Global_Results(全局结果集)可以用于全局错误页的配置等等需要统一使用的模块Struts.XML代码:<package name="user" extends="struts-default" namespace="/user"><global-results><result name="mainpage">/main.jsp</result></global-results><action name="user" class="com.action.UserAction"><result name="success">/ success.jsp</result><result name="error">/error.jsp</result></action></package><!-- 为在其他包中任然可以使用此结果集,继承自那个包 --><package name="admin" namespace="/admin" extends="user"><action name="admin" class="com.action.AdminAction"><result>/admin.jsp</result></action></package>UserAction代码:public String execute(){if(type==1){return SUCCESS;}else if(type==2){return ERROR;}else {return "mainpage";}}AdminAction代码:public String admin(){return "mainpage";}十四: Dynamic_Results(动态结果集)Action代码:private int type;(setter()和getter())private String r; (setter()和getter())public String execute() throws Exception {if(type == 1) r="/user_success.jsp";else if (type == 2) r="/user_error.jsp";return "success";}XML代码: <package name="default" namespace="/" extends="struts-default"><action name="test" class="com.demo.TestAction"><result>${r}</result><!--由于r是action的属性,存在valuestack中,所以${r}可以取得到--></action></package>十五:带参数的结果集(客户端跳转时候才用到)XML代码:<package name="default" namespace="/" extends="struts-default"><action name="test" class="com.demo.TestAction"><result type="redirect">/success.jsp?t=${type}</result></action></package><!-- 原本过程所有Action公用一个值栈(一次request只有一个值栈,服务器端forward共享一个值栈),可以直接访问type属性,现在进行客户端跳转,不共享同一个值栈了,不可以再访问到type属性,所以使用以上方式进行参数的传递 -->Action代码:private int type;(setter()和getter())public String test(){return SUCCESS;}JSP代码: <!-- s:property是从值栈中取值,XML中客户端重新发了一次请求给JSP,但是此时值栈中已经为null了,故而取不到 --> from valueStack:<s:property value="t"/><br> 取不出来from actionContext:<s:property value="#parameters.t"/> 取得出来访问地址:http://localhost:8080/.../...?type=1十六:OGNL(Object Graph Navigation Language对象图导航语言)OGNL1(访问普通属性)(value stack直接取值,stack Context使用#取值)Xml代码:<package name="ognl" extends="struts-default"><action name="ognl" class="com.lp.OgnlAction"><result name="success">/ognl.jsp</result></action></package>Model代码:private String age = "";(setter()/getter())Action代码:private Test test;<!—初始化model可以自己new;也可以传参数,但此时model需要存在空构造方法 --><!-- 使用domainModel时候只有传入类似test.age才能将实体类实例化 -->private String username = "";private String password = ""; (setter()/getter())public String execute(){HttpServletRequest request = ServletActionContext.getRequest();request.setAttribute("name", "liupeng");return SUCCESS;}JSP代码:访问值栈中action的普通属性:username=<s:property value="username"/><br>访问值栈中model的普通属性(getter/setter):<s:property value="test.age"/> <s:property value="test[‘age’]"/> <s:property value="test[\”age\”]"/><s:debug></s:debug>访问属性范围中的普通属性:<s:property value="#request.name"/>访问:http://localhost:8080/OGNL/ognl!execute?username=liupeng&password=1111&test.age=10OGNL2(访问普通属性)Action代码:private Cat cat;(setter/getter)Model代码:Cat.java:private Dog friend;(setter/getter)Dog.java:public Dog(){}private String name = "";(setter/getter)JSP代码: 访问值栈中model的普通属性:<s:property value="cat.friend.name"/>访问:http://localhost:8080/OGNL/ognl!execute?username=liupeng&password=1111&test.age=10&cat.friend.name=wanghanOGNL3(访问普通方法)Action代码:private String password = "";(set/get)public String m(){return "hello";}JSP代码:访问值栈中action属性的普通方法:<s:property value="password.length()"/> 访问值栈中model的普通方法:<s:property value="cat.miaomiao()"/>访问值栈中action的普通方法:<s:property value="m()"/>访问:http://localhost:8080/OGNL/ognl!execute?password=1111OGNL4(访问静态属性和方法)Struts2.x访问静态属性和方法需要在XML文件中加上<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>Action代码:public static String STR = "static string";public static String s(){return "static method";}JSP代码: 访问静态方法:<s:property value="@com.lp.OgnlAction@s()"/><br> 访问静态属性:<s:property value="@com.lp.OgnlAction@STR"/><br> 访问Math类的静态方法:<s:property value="@@math(2,3)"/> <!-- 两个@只能访问一个类的静态方法 -->OGNL4(访问普通类的构造方法)JSP代码:访问普通类的构造方法:<s:property value="new com.model.Test(8)"/>OGNL4(访问集合)Action代码: 注意集合作为了Action的属性存在private List<Test> tests = new ArrayList<Test>();private Set<Dog> dogs = new HashSet<Dog>();private Map<String, Dog> dogMap = new HashMap<String, Dog>();加入setter和getter方法public OgnlAction(){tests.add(new Test(1));tests.add(new Test(2));tests.add(new Test(3));dogs.add(new Dog("dog1"));dogs.add(new Dog("dog2"));dogs.add(new Dog("dog3"));dogMap.put("dog100", new Dog("dog100"));dogMap.put("dog101", new Dog("dog101"));dogMap.put("dog102", new Dog("dog102"));}JSP代码: 访问List:<s:property value="tests"/><br> 访问List中某个元素:<s:property value="tests[0]"/><br> 访问List中元素某个属性的集合<s:property value="tests.{age}"/> 访问List中元素某个属性的集合中的特定值:<s:propertyvalue="tests[0].age"/><s:property value="tests.{age}[0]"/> 访问Set:<s:property value="dogs"/><br> 访问Set中某个元素:<s:property value="dogs[1]"/><br> <!-- set以上是访问不到的,因为set是无序的 -->访问Map:<s:property value="dogMap"/> 访问Map中某个元素:<s:property value="dogMap.dog101"/> <s:property value="dogMap['dog101']"/><s:property value="dogMap[\"dog101\"]"/> 访问Map中所有的key:<s:property value="dogMap.keys"/> 访问Map中所有的value:<s:property value="dogMap.values"/> 访问容器的大小:<s:property value="dogMap.size()"/>OGNL4(投影)投影或者说过滤的是集合中的属性Action代码: 注意集合作为了Action的属性存在private List<Test> tests = new ArrayList<Test>();加入setter和getter方法public OgnlAction(){tests.add(new Test(1));tests.add(new Test(2));tests.add(new Test(3));}JSP代码: 投影(过滤):<s:property value="tests.{?#this.age==1}.{age}"/><br> 投影:<s:property value="tests.{^#this.age>1}.{age}"/><br> 投影:<s:property value="tests.{$#this.age>1}.{age}"/><br> 投影:<s:property value="tests.{$#this.age>1}.{age}==null"/> <!-- ^代表开头,$代表结尾,?代表过滤条件,this表示循环过程中tests对象 -->OGNL5( 用[]访问元素) []:<s:property value="[0] "/><s:property value="[0].username "/> <!-- 访问的是valueStack的从上往下的某个元素 -->十七:Struts标签1.通用标签a)propertyAction代码:private String username ;private String password;(set/get)public String execute(){this.addFieldError("fielderror.test", "wrong");return SUCCESS;}JSP代码: property:<s:property value="username"/><br><!—上面username为Ognl表达式--> property取值为字符串:<s:property value="'username'"/><br>property设定默认值:<s:property value="admin" default="管理员"/><br>property设定HTML:<s:property value="'<hr/>'" escape="false"/><br><!-- escape=true表示不解析html;反之表示解析html -->b)setI.默认为action scope,会将值放入request和ActionConrtext中II.page、request、session、applicationJSP代码: set设定adminName值(默认为request和ActionContext):<s:set var="adminName" value="username"></s:set> set从request取值:<s:property value="#request.adminName"/> set从ActionContext取值:<s:property value="#adminName"/> set设定范围:<s:set name="adminPassword" value="password" scope="page"></s:set> set从相应范围值:<%=pageContext.getAttribute("adminPassword") %><br> set设定var,范围为ActionContext:<s:set var="a" value="password"></s:set>set使用#取值:<s:property value="#a"/>访问:http://localhost:8080/Struts-tags/tags/tags?username=liupeng&password=1111c)bean bean:<s:bean name="com.model.Tags" var="mytag"> <s:param name="userName" value="'liupeng'"></s:param> </s:bean> <!-- var要写才能在debug中看到; param的name应该写Tags的属性,value默认当成Ognl表达式处理 -->读取:<s:property value="#mytag.userName"/><!-- 如果不写var,bean标签会在执行过程中生成一个model对象放到栈顶,但在执行结束后又会消失,使用var就会将值放入ActionContext中,在其他地方也可以使用#访问 --> d)include <s:set var="incPage" value="'/_include.html'"></s:set> <s:include value="%{#incPage}"></s:include><!-- value为String类型,使用%{}将其视为Ognl表达式处理 -->e)param在bean标签处体现f)debug <s:debug></s:debug>2.控制标签a)if elseif elseJSP代码:if elseif else:<br>age:<s:property value="#parameters.age[0]"/><br> <!-- paramaters参数的集合,哪怕只有一个age,也需要精确的定位 --> <s:if test="parameters.age[0]<0">wrong age!</s:if><br><s:elseif test="#parameters.age[0]<30">tooyoung!</s:elseif><br><s:else>yeah!</s:else>访问:http://localhost:8080/Struts-tags/tags/tags? age=20b)iteratorJSP代码: 遍历集合1:<br> <s:iterator value="{1,2,3}"> <s:property/>| <!-- {1,2,3会当成集合,property遍历输出} --></s:iterator>遍历集合2:<s:iterator value="#request.weiboList" var="user"><s:property value="#user.getId()"/>自定义变量:<br> <s:iterator value="{'aaa','bbb','ccc'}" var="x"> <s:property value="#x.toUpperCase()"/> </s:iterator>带有status的遍历: <s:iterator value="{'aaa','bbb','ccc'}" status="status"> <s:property/>| 遍历过的元素总数:<s:property value="#status.count"/>| 遍历过的元素索引:<s:property value="#status.index"/>| 当前访问的个数是偶数:<s:property value="#status.even"/>| 当前访问的个数是奇数:<s:property value="#status.odd"/>| 是first?<s:property value="#status.first"/>| 是last?<s:property value="#status.last"/><br> </s:iterator> 遍历Map集合:<br> <s:iterator value="#{1:'a',2:'b',3:'c'}"> <s:property value="key"/>|<s:property value="value"/> </s:iterator> <s:iterator value="#{1:'a',2:'b',3:'c'}" var="x"> <s:property value="#x.key"/>|<s:property value="#x.value"/> </s:iterator>c)subset3.UI标签a)theme(simple/xhtml(默认)/css_xhtml/ajax)Xml代码:<constant name="struts.ui.theme" value="simple"></constant><package name="theme" namespace="/" extends="struts-default"><action name="theme" class="com.action.ThemeAction"><result name="success">/theme.jsp</result></action></package>JSP代码:在struts.xml中控制theme,默认为xhtml,可以设置为:simple/css_html/ajax<br><s:form> <div class="formFieldError"> <s:fielderror></s:fielderror> </div> <s:textfield name="aaa"></s:textfield></s:form><style type="text/css">.formFieldError ul{list-style-type:none}.formFieldError ul li{list-style-type:none}</style>4.AJAX标签5.$#%的区别$用于i18n和struts配置文件#取得ActionContext值%{}将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用十七:常用常量<!-- 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出 --> <constant name="struts.i18n.encoding" value="UTF-8"/> <!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 --> <constant name="struts.action.extension" value="do"/> <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 --> <constant name="struts.serve.static.browserCache" value="false"/> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --> <constant name="struts.configuration.xml.reload" value="true"/> <!-- 开发模式下使用,这样可以打印出更详细的错误信息 --> <constant name="struts.devMode" value="true" /> <!-- 默认的视图主题 --> <constant name="struts.ui.theme" value="simple" /> <!– 与spring集成时,指定由spring负责action对象的创建 --> <constant name="struts.objectFactory" value="spring" /> <!–该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。 --><constant name="struts.enable.DynamicMethodInvocation" value="false"/> <!--上传文件的大小限制--><constant name="struts.multipart.maxSize" value=“10701096"/>十八:自定义类型转换器HelloWordAction.Javapublic class HelloWordAction {private Date createtime;public Date getCreatetime() {return createtime;}public void setCreatetime(Date createtime) {this.createtime = createtime;}public String execute(){System.out.println(createtime);return "success";}}MyDateCVT.Javapublic class MyDateCVT extends DefaultTypeConverter{@Override public Object convertValue(Map context, Object value, Class toType) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy|MM|dd");try { if(toType == Date.class){//当字符串向Date类型转换时String[] params = (String[]) value;// Request.getParameterValues() return dateFormat.parse(params[0]);}else if(toType == String.class){//当Date转换成字符串时Date date = (Date) value;return dateFormat.format(date);}} catch (ParseException e) {} catch (java.text.ParseException e) {e.printStackTrace();}return null;}}访问http://localhost:8080/servlet/hello?createtime=2013|11|11十八:自定义全局类型转换器将上面的类型转换器注册为全局类型转换器:在WEB-INF/classes下放置xwork-conversion.properties文件 。在properties文件中的内容为:待转换的类型=类型转换器的全类名对于本例而言, xwork-conversion.properties文件中的内容为:java.util.Date= cn.itcast.conversion.DateConverter十九:自定义拦截器Action:package com.filter;import java.sql.Timestamp;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.Interceptor;public class LogIC implements Interceptor{public void destroy() {}public void init() {}public String intercept(ActionInvocation invocation) throws Exception {String actionName = invocation.getAction().getClass().getName();//入口System.out.println("Action execute start at"+new Timestamp(System.currentTimeMillis()));String result = invocation.invoke(); //保证拦截器往下执行//出口return result;}}XML: <package name="hello" namespace="/" extends="struts-default"> <interceptors> <interceptor name="LogIC" class="com.filter.LogIC" /> <interceptor-stack name="LogStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="LogIC" /> </interceptor-stack> </interceptors> <action name="hello" class="com.test.HelloAction" method="execute"><result name="success">/hello.jsp</result><interceptor-ref name="LogStack"/><!-- <default-interceptor-ref name="LogStack"/> 默认的拦截器配置--></action> </package>因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用或者使用如下方式: <package name="hello" abstract="true" extends="struts-default"> <interceptors> <interceptor name="LogIC" class="com.filter.LogIC" /> <interceptor-stack name="LogStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="LogIC" /> </interceptor-stack> </interceptors> </package> <package name="helloTwo" extends="hello"> <action name="hello" class="com.test.HelloAction" method="execute"><result name="success">/hello.jsp</result></action> </package>二十:文件或图片上传1.前台: 2. <struts:form action="weiboAction!uploadPicture.shtml" enctype="multipart/form-data" namespace="/" method="post"> 3. <struts:file name="image" label="文件"></struts:file> 4. <struts:submit value="上传"/> 5. </struts:form> 6. 7. 8.后台: 9. /** 10. * 作者:刘鹏 11. * 时间:2013-07-07 12. * 描述:微博列表中的图片和文件上传显示 13. * @return 14. */ 15. 16./*****************以下为上传部分*******************************/ 17. private File image; //得到上传的文件 18. private String imageFileName; //得到文件的名称,写法是固定的 19. private String imageContentType; //得到文件的类型 20. 21. public String getImageContentType() { 22. return imageContentType; 23. } 24. public void setImageContentType(String imageContentType) { 25. this.imageContentType = imageContentType; 26. } 27. public String getImageFileName() { 28. return imageFileName; 29. } 30. public void setImageFileName(String imageFileName) { 31. this.imageFileName = imageFileName; 32. } 33. public File getImage() { 34. return image; 35. } 36. public void setImage(File image) { 37. this.image = image; 38. } 39. public String addUI(){ 40. return SUCCESS; 41. } 42. public String uploadPicture(){ 43. HttpServletRequest request = ServletActionContext.getRequest(); 44. //保存到根目录下的Images文件夹下 45. String realPath = ServletActionContext.getServletContext().getRealPath("/uploadOImages"); //取得真实路径 46. System.out.println(realPath); 47. System.out.println(imageFileName); 48. System.out.println(imageContentType); 49. 50. //自动命名 51. Random random = new Random(99999); 52. int tempInt = random.nextInt(); 53. Date date = new Date(); 54. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss"); 55. int last = imageFileName.lastIndexOf("."); 56. String head = imageFileName.substring(0,last); 57. String type = imageFileName.substring(last); 58. imageFileName = simpleDateFormat.format(date) + tempInt + type; 59. System.out.println("新的文件名称是:"+imageFileName); 60. 61. //创建父文件夹 62. if(image!=null){ 63. File saveFile = new File(new File(realPath), imageFileName); 64. if(!saveFile.getParentFile().exists()){ //如果Images文件夹不存在 65. saveFile.getParentFile().mkdirs(); //则创建新的多级文件夹 66. 67. } 68. try { 69. FileUtils.copyFile(image, saveFile); //保存文件 70. ActionContext.getContext().put("message", "上传成功!"); 71. request.setAttribute("uploadsuccess", imageFileName); 72. } catch (IOException e) { 73. 74. e.printStackTrace(); 75. } 76. } 77. return "upload"; 78. } 79. 80. 81./*****************以上为上传部分*******************************/ 82. 83.后台将图片的地址保存到数据库中 84. //先从数据库中将所有数据读出来,放入到request中 85. request.setAttribute("weibotest", list); 86. 87.前台使用OGNL语言读取出图片地址,并且显示图片 88. <s:iterator value="#request.weibotest" var="user"> 89. <s:property value="#user.getContent()"/> 90. <img src ='<s:property value ="#user.getImage()" />' width="200"> //显示图片 91. </s:iterator> 二十一:多文件上传第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。第二步:把form表的enctype设置为:“multipart/form-data“,如下:<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/xxx.action" method="post"> <input type="file" name="uploadImages"> <input type="file" name="uploadImages"></form>第三步:在Action类中添加以下属性,属性红色部分对应于表单中文件字段的名称:public class HelloWorldAction{ private File[] uploadImages;//得到上传的文件 private String[] uploadImagesContentType;//得到文件的类型 private String[] uploadImagesFileName;//得到文件的名称 //这里略省了属性的getter/setter方法 public String upload() throws Exception{String realpath = ServletActionContext.getServletContext().getRealPath("/images");File file = new File(realpath);if(!file.exists()) file.mkdirs();for(int i=0 ;i<uploadImages.length; i++){ File uploadImage = uploadImages[i]; FileUtils.copyFile(uploadImage, new File(file, uploadImagesFileName[i]));}return "success"; }}二十二:手工编写代码方式实现对Action中所有方法输入校验通过重写validate() 方法实现, validate()方法会校验action中所有与execute方法签名相同的方法。当某个数据校验失败时,我们应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统的fieldErrors包含失败信息,struts2会将请求转发到名为input的result。在input视图中可以通过<s:fielderror/>显示失败信息。action:public class Validate extends ActionSupport{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public String execute(){return "success";}public void validate() { if(name==null||"".equals(name)){ this.addFieldError("name", "用户名为空!"); }else{ if(name.length()<2||name.length()>10){ this.addFieldError("name", "用户名长度有误!"); } }}}xml:<action name="validate" class="com.test.Validate"><result name="input">/index.jsp</result><result name="success">/hello.jsp</result></action>jsp:<s:fielderror/>二十三:手工编写代码方式实现对Action中指定方法输入校验通过validateXxx()方法实现, validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写。当某个数据校验失败时,我们应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统的fieldErrors包含失败信息,struts2会将请求转发到名为input的result。在input视图中可以通过<s:fielderror/>显示失败信息。action:public String add(){return "success";}public void validateAdd(){ if(name==null||"".equals(name.trim())) this.addFieldError("name", "用户名不能为空");}xml:<action name="validate" class="com.test.Validate"><result name="input">/index.jsp</result><result name="success">/hello.jsp</result></action>jsp:<s:fielderror/>访问:http://localhost:8080/struts/validate!add二十四:输入校验流程1。类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。2。如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息添加到fieldErrors里。不管类型转换是否出现异常,都会进入第3步。3。系统通过反射技术先调用action中的validateXxx()方法,Xxx为方法名。4。再调用action中的validate()方法。5。经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。二十五:基于XML配置方式实现对action的所有方法进行输入校验使用基于XML配置方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类放在同一个包下,文件的取名格式为:ActionClassName-validation.xml,其中ActionClassName为action的简单类名,-validation为固定写法。如果Action类为cn.itcast.UserAction,那么该文件的取名应为:UserAction-validation.xml。action:public class Validate extends ActionSupport{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public String execute(){return "success";}xml:Validate-validation.xml:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.3//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"> <validators> <field name="name"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>用户名不能为空!</message> </field-validator> </field></validators>struts.xml:同上jsp:<s:fielderror/>访问:http://localhost:8080/struts/validate!add二十六:基于XML配置方式实现对action的制定方法进行输入校验当校验文件的取名为ActionClassName-validation.xml时,会对 action中的所有处理方法实施输入验证。如果你只需要对action中的某个action方法实施校验,那么,校验文件的取名应为:ActionClassName-ActionName-validation.xml,其中ActionName为struts.xml中action的名称。action:public class Validate extends ActionSupport{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public String execute(){return "success";}public String add(){return "success";} }xml:Validate-validate-validation.xml:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.3//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"> <validators> <field name="name"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>用户名不能为空!</message> </field-validator> </field></validators>struts.xml:<action name="validate" class="com.test.Validate"><result name="input">/index.jsp</result><result name="success">/hello.jsp</result></action>jsp:<s:fielderror/>访问:http://localhost:8080/struts/validate!add二十七:struts2提供的校验器列表系统提供的校验器如下:required (必填校验器,要求field的值不能为null)requiredstring (必填字符串校验器,要求field的值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)stringlength(字符串长度校验器,要求field的值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)regex(正则表达式校验器,检查被校验的field是否匹配一个正则表达式.expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)fieldexpression(字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)email(邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址)url(网址校验器,要求如果field的值非空,则必须是合法的url地址)date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)conversion(转换校验器,指定在类型转换失败时,提示的错误信息)visitor(用于校验action中的复合属性,它指定一个校验文件用于校验复合属性中的属性)expression(OGNL表达式校验器,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中)二十八:校验器的使用例子required 必填校验器<field-validator type="required"> <message>性别不能为空!</message></field-validator>requiredstring 必填字符串校验器<field-validator type="requiredstring"> <param name="trim">true</param> <message>用户名不能为空!</message></field-validator>stringlength:字符串长度校验器<field-validator type="stringlength"><param name="maxLength">10</param><param name="minLength">2</param><param name="trim">true</param><message><![CDATA[产品名称应在2-10个字符之间]]></message></field-validator>email:邮件地址校验器<field-validator type="email"><message>电子邮件地址无效</message></field-validator>regex:正则表达式校验器<field-validator type="regex"> <param name="expression"><![CDATA[^1[358]\d{9}$]]></param> <message>手机号格式不正确!</message></field-validator>int:整数校验器<field-validator type="int"><param name="min">1</param><param name="max">150</param><message>年龄必须在1-150之间</message></field-validator>字段OGNL表达式校验器<field name="imagefile"><field-validator type="fieldexpression"><param name="expression"><![CDATA[imagefile.length() <= 0]]></param><message>文件不能为空</message></field-validator></field>二十九:基于XML校验的一些特点当为某个action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统按下面顺序寻找校验文件:1。AconClassName-validation.xml2。ActionClassName-ActionName-validation.xml系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于action方法的校验。如果两个校验文件中指定的校验规则冲突,则只使用后面文件中的校验规则。当action继承了另一个action,父类action的校验文件会先被搜索到。假设UserAction继承BaseAction:<action name="user" class="cn.itcast.action.UserAction" method="{1}"></action>访问上面action,系统先搜索父类的校验文件:BaseAction-validation.xml, BaseAction-user-validation.xml,接着搜索子类的校验文件: UserAction-validation.xml, UserAction-user-validation.xml。应用于上面action的校验规则为这四个文件的总和。三十:国际化准备资源文件,资源文件的命名格式如下:baseName_language_country.propertiesbaseName_language.propertiesbaseName.properties其中baseName是资源文件的基本名,我们可以自定义,但language和country必须是java支持的语言和国家。如:中国大陆: baseName_zh_CN.properties美国: baseName_en_US.properties现在为应用添加两个资源文件:第一个存放中文:itcast_zh_CN.properties内容为:welcome=欢迎来到传智播客第二个存放英语(美国): itcast_en_US.properties内容为: welcome=welcome to itcast对于中文的属性文件,我们编写好后,应该使用jdk提供的native2ascii命令把文件转换为unicode编码的文件。命令的使用方式如下:native2ascii 源文件.properties 目标文件.properties配置全局资源与输出国际化信息当准备好资源文件之后,我们可以在struts.xml中通过struts.custom.i18n.resources常量把资源文件定义为全局资源文件,如下:<constant name="struts.custom.i18n.resources" value="itcast" />itcast为资源文件的基本名。后面我们就可以在页面或在action中访问国际化信息:在JSP页面中使用<s:text name=“”/>标签输出国际化信息:<s:text name=“user”/>,name为资源文件中的key在Action类中,可以继承ActionSupport,使用getText()方法得到国际化信息,该方法的第一个参数用于指定资源文件中的key。在表单标签中,通过key属性指定资源文件中的key,如:<s:textfield name="realname" key="user"/>国际化—输出带占位符的国际化信息资源文件中的内容如下:welcome= {0},欢迎来到传智播客{1}在jsp页面中输出带占位符的国际化信息<s:text name="welcome"> <s:param><s:property value="realname"/></s:param><s:param>学习</s:param></s:text>在Action类中获取带占位符的国际化信息,可以使用getText(String key, String[] args)或getText(String aTextName, List args)方法。国际化—JSP中直接访问某个资源文件struts2为我们提供了<s:i18n>标签,使用<s:i18n>标签我们可以在类路径下直接从某个资源文件中获取国际化数据,而无需任何配置:<s:i18n name="itcast"> <s:text name=“welcome”/></s:i18n>Itcast为类路径下资源文件的基本名。如果要访问的资源文件在类路径的某个包下,可以这样访问:<s:i18n name=“cn/itcast/action/package"> <s:text name="welcome"> <s:param>小张</s:param> </s:text></s:i18n>上面访问cn.itcast.action包下基本名为package的资源文件。实例:properties:csst.propertiesmain.company:CSSTmain.addr:haidian,Beijing,chinacsst_zh_CN.propertiesmain.company:中软培训main.addr:海淀南路,北京,中国csst_en_US.propertiesmain.company:&&qqmain.addr:**ssXML:<constant name="struts.custom.i18n.resources" value="csst" /><action name="il8n" class="com.il8n.IL8NAction"><result name="success">/IL8N.jsp</result></action>action:successjsp: 名称:<s:text name="main.company"/><br>地址:<s:text name="main.addr"/>访问:http://localhost:8080/struts/il8n?request_locale=en_US
0 0
- Struts2学习笔记1
- Struts2学习笔记1
- Struts2学习笔记(1)
- Struts2学习笔记(1)
- struts2学习笔记1
- Struts2笔记1
- struts2学习笔记1
- Struts2学习笔记1
- Struts2学习笔记(1)
- struts2注解笔记1
- Struts2.1笔记
- Struts2.1笔记
- struts2学习笔记1
- struts2学习笔记1
- Struts2学习笔记1
- struts2 笔记 1
- Struts2 学习笔记 1
- Struts2笔记--1
- c++知识点小集
- ZipHelper
- Java网络编程(四) Reactor和Proactor模式
- 竖式问题
- 如何将cocos2d-x项目打包成一个.exe
- Struts2.1笔记
- ActionBar的使用总结及相关SDK翻译
- 脑残的设计--- 视图(view)里面包含order by
- Vector的三种构造函数:
- Qt文件读写
- myeclipse+struts中的路径是如何确定的
- nginx php-fpm spawn-fastcgi 两种通信方式
- Hibernate
- ZOJ-1951