(五)Struts之Action类基础(二)

  • 上一章节末((三)Struts之Action类基础(一))介绍了如何获取用户输入数据的获取。接着就是在Struts中怎么把数据响应给用户端,这就必须要求我们把数据放到作用域中,然后才能显示到用户浏览器。

一、将数据放到作用域并在用户浏览器中显示

  A、 使用Servlet原生作用域(request、session、servletContext)

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
String path=request.getContextPath();
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
        <h3>把数据放到Servlet原生作用域(request、session、servletContext)然后显示</h3>
        
        <a href="<%=path%>/scope/scope_1">点我显示数据</a>

    </pre>
</body>
</html>

界面:

struts.xml

<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/scope" extends="struts-default">
        <action name="scope_1" class="scope.ActionScope_1">
        <result name="show">/show.jsp</result>
        </action>
    </package>

</struts>

 ActionScope.java

package scope;

import action.BaseAction;

public class ActionScope_1  extends BaseAction{

    @Override
    public String execute() {
    
        request.setAttribute("request_key", "request作用域的值");
        session.setAttribute("session_key", "session作用域的值");
        servletContext.setAttribute("servletContext_key", "servletContext作用域的值");
        return "show";
    }
}

show.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
                <h3>显示放在作用域中的数据</h3>
        request作用域的值为:${requestScope.request_key }
        session作用域的值为:${sessionScope.session_key }
        servletContext作用域的值为:${applicationScope.servletContext_key }
    </pre>
</body>
</html>

结果:

  B、使用struts封装的作用域

  •  使用struts封装的作用域,把reuqest、session、servletContext作用域封装成Map

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
String path=request.getContextPath();
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
        <h3>把数据放到Struts封装的作用域中然后显示</h3>
        
        <a href="<%=path%>/scope/scope_2">点我显示数据</a>

    </pre>
</body>
</html>

界面:

  • struts.xml
<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/scope" extends="struts-default">
        <action name="scope_2" class="scope.ActionScope_2">
        <result name="show">/show.jsp</result>
        </action>
    </package>

</struts>
  • ActionScope_2.java
package scope;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

import action.BaseAction;

public class ActionScope_2  extends BaseAction{
/**
 * 用Struts封装的作用域ActionContext(Action上下文)存放数据
 * ActionContext和ServletActionContext的区别,ServletActionContext用于
 * 获取servlet原生对象
 * ActionContext把servlet作用域封装成Map
 */
    
    @Override
    public String execute() {
        ActionContext actionContext=ActionContext.getContext();
        //request作用域的获取比较特殊
        //获取action封装后的作用域
        Map<String,Object> requestMap=(Map<String,Object>)actionContext.get("request"); 
        Map<String,Object> sessionMap=actionContext.getSession();
        Map<String,Object> applicationMap=actionContext.getApplication();
        
        //在作用域中存放数据
        requestMap.put("requestMap_key", "requset中的值1");
        sessionMap.put("sessionMap_key", "sessionMap中的值1");
        applicationMap.put("applicationMap_key", "applicationMap中的值1");
        return "show";
    }

}
  • show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
                <h3>显示放在作用域中的数据</h3>
        request作用域的值为:${requestScope.requestMap_key }
        session作用域的值为:${sessionScope.sessionMap_key }
        servletContext作用域的值为:${applicationScope.applicationMap_key }
    </pre>
</body>
</html>

结果:

  • 解析: Struts中通过ActionContext这个静态类可以得到request、session、servletContext作用域,并把这些作用于封装成Map对象,而在JSP页面中,通过EL表达式获取作用域中的值的方式没有改变,${requestScope.value1 }或${sessionScope.value2}或${applicationScope.value3}


  •  上述例子中显示数据的方式是EL表达式,在Struts中可以用Struts的方式来显示数据。

二、数据在页面上的显示

  A、 使用EL表达式+JSTL标签

以上述例子所示,index.jsp和struts.xml和ActionScope_2.java文件均与上例一样,show.jsp如下:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3  <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11     <pre>
12                 <h3>El表达式+JSTL标签显示放在作用域中的数据</h3>        
13         <c:if test="${requestScope.requestMap_key==null}">        
14             <c:out value="${requestScope.requestMap_key}"></c:out>    
15         </c:if>
16 
17         session作用域的值为:${sessionScope.sessionMap_key }
18         servletContext作用域的值为:${applicationScope.applicationMap_key }
19     </pre>
20 </body>
21 </html>
  •  注意第13行中的语句${requestScope.requestMap_key==null} 如果requestScope中的requestMap_key值等于null的话就显示出来,否则不显示,结果如下,并不显示reqeuset作用域中的数据,说明JSTL+EL表达式成功运行:

  B、使用OGNL表达式+Struts标签

  •  Struts标签中不能用EL表达式,如<s:if test="${sessionScope.sessionMap_key}" 这是错的<s:if>是struts标签,而${sessionScope.sessionMap_key是el表达式。同理,JTSL标签中不能用OGNL表达式。
  •  以上述例子所示,index.jsp和struts.xml和ActionScope_2.java文件均与上例一样,show.jsp如下:
 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3  <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 4  <%@ taglib prefix="s" uri="/struts-tags" %>
 5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 6 <html>
 7 <head>
 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 9 <title>Insert title here</title>
10 </head>
11 <body>
12     <pre>
13                 <h3>El表达式+JSTL标签显示放在作用域中的数据</h3>        
14         <c:if test="${requestScope.requestMap_key==null}">        
15             <c:out value="${requestScope.requestMap_key}"></c:out>    
16         </c:if>
17 
18         <h3>OGNL表达式+Struts标签显示放在作用域中的数据</h3>
19     
20     <s:if test="#request.requestMap_key!=null"> 
21         <s:property value="#request.requestMap_key"/>
22     </s:if>
23     </pre>
24 </body>
25 </html>
  • 注意EL表达式和OGNL表达式取值的方法,EL表达式取出reqeuse、session、application作用域中值的方法为requestScope.属性名【sessionScope.属性名】【applicationScope.属性名】  而OGNL表达式取出作用域中的值的方法为#request.属性名【#session.属性名】【#application.属性名


三、Struts和servlet同时使用

  •  当我们部署好Struts之后,web.xml中的

 <filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  • 会拦截一切页面,其中如果定义了一个servlet,也会把当作action处理。比如当URL=“工程名/servlet/TestServlet”
  • web.xml
 <servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/servlet/test</url-pattern>
  </servlet-mapping>

我们希望会执行servlet.TestServlet这个servlet类,但是实际上被struts拦截器当成action了,就去struts.xml中找命名空间为/servlet的action名为TestServlet,但是找不到于是就是报错。

  • 解决上述问题的方法

要解决这个问题就不得不提起struts.xml中的一个常量<constant name="struts.action.extension" value="=action,,"/> 默认也是这个,意思是对于所有的请求后缀名为action或者为空的请求,都会被拦截,并到struts.xml中寻找相对应的Action.

      A、 解决方法1 :将servlet的后缀名更改为与Struts中常量(struts.action.extension)不一样的后缀名,适用于servlet文件比较少的项目

      B、 解决方法2:将struts的后缀名改掉,适用于struts文件比较少的项目,比如:

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>

     C、解决方法3: 当项目中struts和servlet文件都差不多的话,如果改后缀名会很麻烦,那么我们可以重写StrutsPrepareAndExecuteFilter里的方法,即如下配置:

web.xml

<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>
  <servlet>
<servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/servlet/test</url-pattern>
  </servlet-mapping

如上,无论访问哪个页面都会被Struts的StrutsPrepareAndExecuteFilter这个过滤器拦截然后转到Struts.xml中解析,如果Struts和sevlet中都不添加后缀名的话,servlet就无法被访问到。

  • 具体方法:    1.   定义一个类,继承StrutsPrepareAndExecuteFilter这个过滤器,重写doFilter()方法,

           2.   在web.xml中把 StrutsPrepareAndExecuteFilter过滤器换成我们定义的类。

  • 解决方法3示例:

index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
String path=request.getContextPath();
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
    <a href="<%=path%>/servlet/test">点击跳转到servlet页面</a>
    </pre>
</body>
</html>
  • a标签中的请求为servlet请求
  • StrutsFilter.java 这个类重写了StrutsPrepareAndExecuteFilter过滤器中的doFilter()方法,
package filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter;

public class StrutsFilter extends StrutsPrepareFilter{

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
    /**
     * 判断请求是sevlet还是struts请求
     *     
     */
        HttpServletRequest request=(HttpServletRequest)req;    
        String requestPath=request.getRequestURI();
        
        if(requestPath.indexOf("/servlet/") !=-1){
            //请求为servlet请求,如果是servlet请求则跳过这个过滤器让下一个过滤器来处理。
            System.out.println("aaa");
            chain.doFilter(req, res);
                
        }else{
            //请求为struts请求,是struts请求直接让父类来处理
            System.out.println("bbb");
            super.doFilter(req, res, chain);
        }        
    }
}
  • 最后修改web.xml配置。 web.xml
 <filter>
    <filter-name>struts2</filter-name>
    <filter-class>filter.StrutsFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/servlet/test</url-pattern>
  </servlet-mapping>

 如上述,StrutsPrepareAndExecuteFilter换成了我们自己定义的类。


  • 解决方法1示例:
  • index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
String path=request.getContextPath();
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <pre>
      <a href="<%=path%>/servlet/test.do">点击跳转到servlet页面</a>
    </pre>
</body>
</html>
  • struts.xml
<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.action.extension" value="=action,,"/>
    <package name="default" namespace="/scope" extends="struts-default">
        <action name="scope_2" class="scope.ActionScope_2">
        <result name="show">/show.jsp</result>
        </action>
    </package>

</struts>
  • web.xml
  <servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/servlet/test.do</url-pattern>
  </servlet-mapping>
  •  TestServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out=response.getWriter();
        
        
        out.print("我是servlet");
    }

结果:


原文地址:https://www.cnblogs.com/shyroke/p/6553811.html