public class ParmValueAction extends ActionSupport
{ private Usere user; @Override public String execute() throws Exception { ActionContext ctx = ActionContext.getContext(); HttpServletRequest req = ServletActionContext.getRequest(); Map<String, Object> requestMap = (Map<String, Object>) ctx .get("request"); ctx.put("userKey", user); requestMap.put("userReqMap", user); req.setAttribute("userReq", user); return SUCCESS; } public Usere getUser() { return user; } public void setUser(Usere user) { this.user = user; } } jsp: 方法1: 使用property标签 <br> <s:property value="user.name"/> <s:property value="user.age"/> <br> 方法2: 使用property标签,使用#userKey对值栈进行查找 <br> <s:property value="#userKey.name"/> <s:property value="#userKey.age"/> <br> 方法3: 使用property标签,使用#action对值栈进行查找,同时使用默认的查找方式,该方法等同于方法1,在2.0中该方法不可用,2.1可用 <br> <s:property value="#action.user.name"/> <s:property value="#action.user.age"/> <br> 方法4: 使用property标签,使用#userReq对值栈进行查找,这里查不到该值,因为值栈中没有这个key <br> <s:property value="#userReq.user.name"/> <s:property value="#userReq.user.age"/> <br> 方法5: 使用property标签,使用#userReqMap对值栈进行查找,这里查不到该值,因为值栈中没有这个key <br> <s:property value="#userReqMap.name"/> <s:property value="#userReqMap.age"/> <br> <hr> request取值方法,取保存在userReqMap中的user: <br> <s:property value="#request.userReqMap.name"/> <s:property value="#request.userReqMap.age"/> <br> request取值方法,取保存在userKey中的user: <br> <s:property value="#request.userKey.name"/> <s:property value="#request.userKey.age"/> <br> request取值方法,取保存在userReq中的user: <br> <s:property value="#request.userReq.name"/> <s:property value="#request.userReq.age"/> <br> request取值方法1,取保存在action中的user: <br> <s:property value="#request.user.name"/> <s:property value="#request.user.age"/> <br> request取值方法2,取保存在action中的user: <br> <s:property value="#request.action.user.name"/> <s:property value="#request.action.user.age"/> <br> <hr> jstl取值方法,取保存在userReq中的user: <br> <c:out value="${request.userReq.name}"></c:out> <c:out value="${request.userReq.age}"></c:out> <br> jstl取值方法,取保存在userReqMap中的user: <br> <c:out value="${request.userReqMap.name}"></c:out> <c:out value="${request.userReqMap.age}"></c:out> <br> jstl取值方法,取保存在userKey中的user: <br> <c:out value="${request.userKey.name}"></c:out> <c:out value="${request.userKey.age}"></c:out> <br> jstl取值方法1,取保存在action中的user: <br> <c:out value="${request.user.name}"></c:out> <c:out value="${request.user.age}"></c:out> <br> jstl取值方法2,通过action取保存在action中的user: <br> <c:out value="${request.action.user.name}"></c:out> <c:out value="${request.action.user.age}"></c:out> <br> <hr> 直接使用java编码来取: <% Usere user = (Usere)request.getAttribute("userReq"); Usere userMap = (Usere) request.getAttribute("userReqMap"); Usere userKey = (Usere) request.getAttribute("userKey"); //2.0中无法取到action,本次测试的版本为2.1.8.1 ParmValueAction action=(ParmValueAction)request.getAttribute("action"); //Usere userAction=action.getUser(); //String name=userAction.getName(); //int age=userAction.getAge(); %> 直接取: <%=user.getName() %> <%=user.getAge() %> <br> 取userMap: <%=userMap.getName()%> <%=userMap.getAge()%> <br> 取userKey: <%=userKey.getName()%> <%=userKey.getAge()%> <br> 取 action: <%=action.getUser().getName()%> <%=action.getUser().getAge()%> </body> 结果: 方法1: 使用property标签 terje 25 方法2: 使用property标签,使用#userKey对值栈进行查找 terje 25 方法3: 使用property标签,使用#action对值栈进行查找,同时使用默认的查找方式,该方法等同于方法1,在2.0中该方法不可用,2.1可用 terje 25 方法4: 使用property标签,使用#userReq对值栈进行查找,这里查不到该值,因为值栈中没有这个key 方法5: 使用property标签,使用#userReqMap对值栈进行查找,这里查不到该值,因为值栈中没有这个key request取值方法,取保存在userReqMap中的user: terje 25 request取值方法,取保存在userKey中的user: terje 25 request取值方法,取保存在userReq中的user: terje 25 request取值方法1,取保存在action中的user: terje 25 request取值方法2,取保存在action中的user: terje 25 jstl取值方法,取保存在userReq中的user: terje 25 jstl取值方法,取保存在userReqMap中的user: terje 25 jstl取值方法,取保存在userKey中的user: terje 25 jstl取值方法1,取保存在action中的user: terje 25 jstl取值方法2,通过action取保存在action中的user: terje 25 直接使用java编码来取: 直接取: terje 25 取userMap: terje 25 取userKey: terje 25 取 action: terje 25 原因:通过查看 org.apache.struts2.dispatcher.StrutsRequestWrapper 源代码,以下这段代码是apache社区对Request做了包装,这样包装如果在页面中通过传统的取值方法找不到值,就到值栈中去找,这样一来不仅兼容了jstl和java代码直接取值,同时也保证struts2的标签能顺利取到值。 public Object getAttribute(String s) { if (s != null && s.startsWith("javax.servlet")) { // don't bother with the standard javax.servlet attributes, we can short-circuit this // see WW-953 and the forums post linked in that issue for more info return super.getAttribute(s); } ActionContext ctx = ActionContext.getContext(); Object attribute = super.getAttribute(s); if (ctx != null) { if (attribute == null) { boolean alreadyIn = false; Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute"); if (b != null) { alreadyIn = b.booleanValue(); } // note: we don't let # come through or else a request for // #attr.foo or #request.foo could cause an endless loop if (!alreadyIn && s.indexOf("#") == -1) { try { // If not found, then try the ValueStack ctx.put("__requestWrapper.getAttribute", Boolean.TRUE); ValueStack stack = ctx.getValueStack(); if (stack != null) { attribute = stack.findValue(s); } } finally { ctx.put("__requestWrapper.getAttribute", Boolean.FALSE); } } } } return attribute; } |