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; }