• 上一章节末((三)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如下:

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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>El表达式+JSTL标签显示放在作用域中的数据</h3>
<c:if test="${requestScope.requestMap_key==null}">
<c:out value="${requestScope.requestMap_key}"></c:out>
</c:if> session作用域的值为:${sessionScope.sessionMap_key }
servletContext作用域的值为:${applicationScope.applicationMap_key }
</pre>
</body>
</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如下:
 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>El表达式+JSTL标签显示放在作用域中的数据</h3>
<c:if test="${requestScope.requestMap_key==null}">
<c:out value="${requestScope.requestMap_key}"></c:out>
</c:if> <h3>OGNL表达式+Struts标签显示放在作用域中的数据</h3> <s:if test="#request.requestMap_key!=null">
<s:property value="#request.requestMap_key"/>
</s:if>
</pre>
</body>
</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");
}

结果:


(五)Struts之Action类基础(二)的更多相关文章

  1. (三)Struts之Action类基础(一)

    一.Action的类型 A.使用普通的类 必须有public的execute且返回值为String的方法. ActionType.java package com; public class Acti ...

  2. 初次了解struts的action类

    Action类真正实现应用程序的事务逻辑,它们负责处理请求.在收到请求后,ActionServlet会为这个请求选择适当的Action 如果需要,创建Action的一个实例 调用Action的perf ...

  3. Struts2 之 Action 类访问 WEB 资源

    接着上次博客的内容我继续分享我所学到的知识,和自己在学习过程中所遇到问题以及解决方案.当然,如果读者发现任何问题均可以在下方评论告知我,先谢! 在 Action 中访问 WEB 资源 web 资源 所 ...

  4. 第五课 Struts的控制器【续】Action类的execute()方法

    1.Action类的execute()方法: public ActionForward execute(ActionMapping mapping,                           ...

  5. Bootstrap <基础二十五>警告(Alerts)

    警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...

  6. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解

    1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...

  7. DRF框架(五)——context传参,二次封装Response类,两个视图基类(APIView/GenericAPIView),视图扩展类(mixins),子类视图(工具视图),视图集(viewsets),工具视图集

    复习 1.整体修改与局部修改 # 序列化get (给前端传递参数) #查询 ser_obj = ModelSerializer(model_obj) #只传递一个参数,默认是instance的参数,查 ...

  8. stuts1:(Struts)Action类及其相关类

    org.apache.struts.action.Action类是Struts的心脏,也是客户请求和业务操作间的桥梁.每个Action类通常设计为代替客户完成某种操作.一旦正确的Action实例确定, ...

  9. JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表

    一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...

随机推荐

  1. TXMLDocument 的使用

    TXMLDocument 的使用 TXMLDocument是DELPHI自带的操作XML的类. 需要它,需要引用单元: uses XMLDoc; var XMLDoc:TXMLDocument; XM ...

  2. TynSerial类介绍

    TynSerial类介绍 TynSerial是咏南中间件封装的,支持数据二进制序列(还原)的类. 支持WINDOWS.LINUX.MAC.IOS.ANDROID. 支持D6及以上版本. 支持TCP/H ...

  3. RabbitMQ 3.7.X集群:从入门到精通,这一篇就够了

    RabbitMQ是流行的开源消息队列系统,本身已经具备了较强的并发处理速度及运行稳定性,然而在大规模的实际应用中,往往还需要使用集群配置来保证系统中消息通信部分的高可用性,并发处理性能及异常恢复能力. ...

  4. PHP松散比较与严格比较的区别详解

    在PHP中相等的比较有两种,松散比较和严格比较,当使用松散比较时,如果进行比较的两个操作数类型不同,那么会对操作数进行适当的类型转换,如果转换后的值相同则认为两个操作数相等.而使用严格比较时,如果两个 ...

  5. NULL和nullptr

    NULL就是0 nullptr是空指针[c++11]

  6. 一百四十:CMS系统之使用flask-paginate实现分页功能

    官方文档:https://pythonhosted.org/Flask-paginate/ 安装:pip install flask-paginate 在没有分页的情况下,默认会加载所有内容 在con ...

  7. jenkins报错集合

    可能会碰到以下报错: 1)这里的失败原因是因为运行jenkins程序的是jenkins用户,我们连接节点的秘钥是root的,所以现在连接不上 打开配置文件/var/lib/jenkins 将jenki ...

  8. (十一)会话跟踪技术之作用域(request、session、servletContext)

    一.作用域范围 Request       保存的键值仅在下一个request对象中可以得到,作用于两个有请求关系的页面 Session        它是一个会话范围,相当于一个局部变量,从Sess ...

  9. iOS compile sources问题

    以前xcode compile sources 这里是自动生成的,升级到新版本之后,我删掉这里的列表,就没法生成了.导致项目无法运行. 解决方法就是:自己手动添加.h文件

  10. Python3之返回函数

    参考:https://www.cnblogs.com/mzc1997/p/7641995.html Python中函数不仅可以作为参数还可以作为结果返回 >>> def pro1(c ...