• 上一章节末((三)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. SQL中AVG()、COUNT()、SUM()等函数对NULL值处理

    一.AVG() 求平均值 注意AVE()忽略NULL值,而不是将其作为“0”参与计算 二.COUNT() 两种用法 1.COUNT(*) 对表中行数进行计数 不管是否有NULL 2.COUNT(字段名 ...

  2. ObjectAnimator简单示例

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  3. Qt编写控件属性设计器8-网络采集

    一.前言 上一篇文章已经打通了数据源之一的串口采集,这次要说的是网络采集,网络通信目前用的最多的是三种,TCP/UDP/HTTP,其中tcp通信又包括了客户端服务端两种,tcp通信才用了多次握手机制不 ...

  4. kubenetes创建一个pod应用

    Pod是可以创建和管理Kubernetes计算的最小可部署单元.一个Pod代表着集群中运行的一个进程.每个pod都有一个唯一的ip. 一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker) ...

  5. LeetCode_121. Best Time to Buy and Sell Stock

    121. Best Time to Buy and Sell Stock Easy Say you have an array for which the ith element is the pri ...

  6. HTTP连接详解

  7. 取数据超过内存限制的问题-解决方案(sample,takeSample,filter)

    遇到的问题 在处理数据过程中,遇到需要取(n)个数的问题,而当样本量过大的时候,就不能简单的take(n),这类问题一般有两种情况: > - 有序取 TopN > - 无序取 N 先来讨论 ...

  8. spark报错:invalid token

    启动spark报错,启动container失败,去看yarn的日志,显示invalid token, 经过排查是hadoop子节点的配置和主节点的配置不一致导致的,同步之后,问题解决.

  9. vs2015配置link.exe环境变量

    https://www.cnblogs.com/johnwii/p/4966086.html

  10. MySQL5.7查看数据存储位置

    在MySQL客户端执行如下命令查看MySQL的数据存放位置: mysql> show global variables like "%datadir%"; +-------- ...