环境搭建 1.1 jar 1.2 web.xml 1.3 struts.xml struts.xml(核心配置文件) 目录结构: Struts.xml Struts.base.xml regex:. Struts.sy.xml /hello.jsp 1.2、Actionu 不需要指定父类(ActionSupport)u 业务方法的定义 public String xxx();//executeu Action是多例模式(注:在spring中的配置中一定要注意) Action用来接收参数 1.3、参数赋值u Action中定义属性,并提供get/set方法 userName, getUserName/setUserName u ModelDriven 返回实体,不能为null,不需要提供get/set方法 u ModelDriven返回实体和Action中属性重名,ModelDriven中优先级更高 注:ognl,ActionContext学完就知道了 案例:Action代码(user1不提供set、get方法):private String uname; private User user1 = new User(); private User user2; public String execute() { System.out.println(“uname:”+uname); System.out.println(“user1:”+user1); System.out.println(“user2:”+user2); return “hello”; } 浏览器输入:http://localhost:8080/Y2_struts_ognl/sy/helloAction?uname=zs结果: 之后 说明modeldriven接口拦截了uname赋值 浏览器输入:http://localhost:8080/Y2_struts_ognl/sy/helloAction?user2.uname=zs结果: 说明struts支持对象导航 1.4、 与J2EE容器交互u 非注入 耦合(ServletActionContext) 解耦(建立使用解耦模式(ActionContext) u 注入 耦合(XxxAware) 解耦 1.5 核心文件配置u include 包含文件 file u package 包 name 包名 extends 继承 namespace 虚拟路径 abstract 通常用来被继承 u action 子控制器 name:helloAction,helloAction_ class 全限定名 method:execute,{1} u result 结果码处理 Name 结果码配置 type:dispatcher|redirect 1.6、动态方法调用 /rs.jsp 注1:动态方法调用,新版本中已禁用,可自行开启或关闭注2:子控制器的访问路径:名称空间+"/"+子控制器名字_xxx+".action" 2、Ognl1、OGNL的全称是Object Graph Navigation Language(对象图导航语言),它是一种强大的表达式语言2、OgnlContext(ongl上下文)其实就是Map (教室、老师、学生)OgnlContext=根对象(1)+非根对象(N)非根对象要通过"#key"访问,根对象可以省略"#key" 注1:context:英文原意上下文,环境/容器 3、根对象和非根对象的理解4、ValueStack 先进后出的数据结构,弹夹 push/pop 使用ValueStack作为根对象,是因为放到值栈中的对象都可视为根对象5、struts2中传递数据可以使用作用域,但更多的是利用ValueStack或ActionContext作用域取值:从小到大(page -> request -> session -> application)ValueStack取值:从上到下 作用域取值: r e s u l t , r e s u l t 是 一 个 k e y , 是 一 个 字 符 串 。 V a l u e S t a c k 取 值 : < s : p r o p e r t y v a l u e = " r e s u l t " / > , r e s u l t 是 一 个 表 达 式 。 6 、 保 证 同 一 请 求 中 只 创 建 一 个 上 下 文 图 解 : a c t i o n C o n t e x t 上 下 文 就 好 比 一 个 大 容 器 其 中 根 对 象 容 器 : v a l u e s t a c k 非 跟 对 象 容 器 : r e q u e s t 、 s e s s i o n 、 a p p l i c a t i o n 、 p a r a m e t e r s V a l u e s t a c k 中 始 终 是 从 上 往 下 去 找 属 性 值 , 找 到 后 就 不 会 向 下 去 找 了 。 N a m e : 小 明 同 学 S a l a r y : 2000 因 为 v s 中 最 上 面 的 是 S t u d e n t 对 象 、 其 次 是 E m p l o y e e 对 象 。 S t u d e n t 对 象 中 没 有 s a l a r y 属 性 , 会 在 e m p l o y e e 对 象 中 去 找 。 p u b l i c S t r i n g e x e c u t e ( ) A c t i o n C o n t e x t c o n t e x t = A c t i o n C o n t e x t . g e t C o n t e x t ( ) ; / / 栈 : 表 示 一 个 先 进 后 出 的 数 据 结 构 V a l u e S t a c k v s = c o n t e x t . g e t V a l u e S t a c k ( ) ; / / p u s h 方 法 把 项 压 入 栈 顶 v s . p u s h ( n e w E m p l o y e e ( " z s " , 22 ) ) ; v s . p u s h ( n e w E m p l o y e e ( " l s " , 22 ) ) ; v s . p u s h ( n e w E m p l o y e e ( " w w " , 22 ) ) ; / / p o p 方 法 移 除 栈 顶 对 象 并 作 为 此 函 数 的 值 返 回 该 对 象 E m p l o y e e e = ( E m p l o y e e ) v s . p o p ( ) ; S y s t e m . o u t . p r i n t l n ( e . g e t N a m e ( ) ) ; e = ( E m p l o y e e ) v s . p o p ( ) ; S y s t e m . o u t . p r i n t l n ( e . g e t N a m e ( ) ) ; e = ( E m p l o y e e ) v s . p o p ( ) ; S y s t e m . o u t . p r i n t l n ( e . g e t N a m e ( ) ) ; v s . p u s h ( n e w E m p l o y e e ( " 张 雇 员 " , 2000 ) ) ; / / 1 v s . p u s h ( n e w S t u d e n t ( " 小 明 同 学 " , " s 001 " ) ) ; / / 0 S y s t e m . o u t . p r i n t l n ( v s . f i n d V a l u e ( " n a m e " ) ) ; S y s t e m . o u t . p r i n t l n ( v s . f i n d V a l u e ( " s a l a r y " ) ) ; r e t u r n n u l l ; 一 次 请 求 只 生 成 一 个 a c t i o n c o n t e x t 对 象 < {result },result 是一个key,是一个字符串。ValueStack取值:<s:property value="result"/>,result 是一个表达式。6、保证同一请求中只创建一个上下文 图解:actionContext上下文就好比一个大容器其中根对象容器:valuestack非跟对象容器:request、session、application、parameters Valuestack中始终是从上往下去找属性值,找到后就不会向下去找了。Name:小明同学Salary:2000因为vs中最上面的是Student对象、其次是Employee对象。Student对象中没有salary属性,会在employee对象中去找。 public String execute() { ActionContext context = ActionContext.getContext(); // 栈:表示一个先进后出的数据结构 ValueStack vs = context.getValueStack(); // push方法把项压入栈顶 vs.push(new Employee("zs", 22)); vs.push(new Employee("ls", 22)); vs.push(new Employee("ww", 22)); // pop方法移除栈顶对象并作为此函数的值返回该对象 Employee e = (Employee) vs.pop(); System.out.println(e.getName()); e = (Employee) vs.pop(); System.out.println(e.getName()); e = (Employee) vs.pop(); System.out.println(e.getName()); vs.push(new Employee("张雇员", 2000));// 1 vs.push(new Student("小明同学", "s001"));// 0 System.out.println(vs.findValue("name")); System.out.println(vs.findValue("salary")); return null; } 一次请求只生成一个actioncontext对象 <% ActionContext context = ActionContext.getContext(); System.out.println(context); %> 3、struts标签3.1、通用标签u 数据标签 property set scope="action",action=request+actionContext push 修改页面 param <param name="color">blue</param> <param name="color" value="blue"/> 注1:它是子标签 注2:url/action date java.text.SimpleDateFormat/DecimalFormat debug url/param/a Action <h1>property标签</h1> <s:property default="xxx" value="result" /> <h1>set标签</h1> <s:set var="result" value="uname" scope="action" /> action: <s:property value="result" /> <br> request: result,result是一个key,是一个字符串。ValueStack取值:<s:propertyvalue="result"/>,result是一个表达式。6、保证同一请求中只创建一个上下文图解:actionContext上下文就好比一个大容器其中根对象容器:valuestack非跟对象容器:request、session、application、parametersValuestack中始终是从上往下去找属性值,找到后就不会向下去找了。Name:小明同学Salary:2000因为vs中最上面的是Student对象、其次是Employee对象。Student对象中没有salary属性,会在employee对象中去找。publicStringexecute()ActionContextcontext=ActionContext.getContext();//栈:表示一个先进后出的数据结构ValueStackvs=context.getValueStack();//push方法把项压入栈顶vs.push(newEmployee("zs",22));vs.push(newEmployee("ls",22));vs.push(newEmployee("ww",22));//pop方法移除栈顶对象并作为此函数的值返回该对象Employeee=(Employee)vs.pop();System.out.println(e.getName());e=(Employee)vs.pop();System.out.println(e.getName());e=(Employee)vs.pop();System.out.println(e.getName());vs.push(newEmployee("张雇员",2000));//1vs.push(newStudent("小明同学","s001"));//0System.out.println(vs.findValue("name"));System.out.println(vs.findValue("salary"));returnnull;一次请求只生成一个actioncontext对象<{result }
url/param标签
<s:set var=“blue” value=“result” /> <s:url var=“url1” namespace="/sy" action=“tagAction_formSubmit”> <s:param name=“color1” value=“blue”></s:param> <s:param name=“color2”>blue</s:param> </s:url> <s:property value="#url1" />date标签
<% request.setAttribute(“d”, new Date()); %> <s:date name="#request.d" format=“yyyyMMdd” /> <s:debug />push标签
控制标签
<s:if test="#request.score >= 90"> A </s:if> <s:elseif test="#request.score >= 80"> B </s:elseif> <s:elseif test="#request.score >= 70"> C </s:elseif> <s:elseif test="#request.score >= 60"> D </s:elseif> <s:else> E </s:else>- <s:iterator var=“v” value="#request.names">
- <s:property value="#v" />
- </s:iterator>
序号 | 学号 | 姓名 | 拼音 | 性别 | 标记 | 班级 | 操作 |
序号 | <s:property value="#s.sid"/> | <s:property value="#s.sname"/> | <s:property value="#s.spin"/> | <s:property value="#s.sex"/> | <s:property value="#s.mark"/> | <s:property value="#s.cname"/> | <s:url var=“durl” namespace="/sy" action=“studentAction_del”> <s:param name=“sid” value="#s.sid"/> </s:url> <s:a href="%{#durl}">删除</s:a> <s:url var=“eurl” namespace="/sy" action=“studentAction_load”> <s:param name=“sid” value="#s.sid"/> </s:url> <s:a href="%{#eurl}">修改</s:a> |
private String fileContentType;
private String fileFileName;开头的file与文件传递的name相对应enctype=“multipart/form-data” private String uploadDir = “/upload”;// web项目下的目录,虚拟路径,会跟随服务器的位置而改变 Jsp上传页面 Jsp下载页面<s:url var=“saveAsUrl” namespace="/sy" action=“userFileUpload_saveAs.action”></s:url><s:property value=“saveAsUrl”/><s:a href="%{#saveAsUrl}">直接打开</s:a> <s:url var=“openAsUrl” namespace="/sy" action=“userFileUpload_openAs.action”></s:url><s:property value=“openAsUrl”/> Xml配置 /querySuccess.jsp Java类 结果