• 上一章节末((三)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. 文件CRC和MD5校验

    文件CRC和MD5校验 CRC和MD5用于文件和数据的传输校验,以确认是否接收成功. unit CRCMD5; interface { 获取文件CRC校验码 } function GetFileCRC ...

  2. Feed流系统设计-总纲

    https://mp.weixin.qq.com/s/ccxM2thPbzg5vDWgGVJ5vQ 作者:少强 简介 差不多十年前,随着功能机的淘汰和智能机的普及,互联网开始进入移动互联网时代,最具代 ...

  3. Spring Boot属性配置&自定义属性配置

    一.修改默认配置 例1.spring boot 开发web应用的时候,默认tomcat的启动端口为8080,如果需要修改默认的端口,则需要在application.properties 添加以下记录: ...

  4. 字典学习(Dictionary Learning)

    0 - 背景 0.0 - 为什么需要字典学习? 这里引用这个博客的一段话,我觉得可以很好的解释这个问题. 回答这个问题实际上就是要回答“稀疏字典学习 ”中的字典是怎么来的.做一个比喻,句子是人类社会最 ...

  5. C#依赖注入实例

    http://qing.weibo.com/tj/400082fa33001h7x.html 1.5 实现依赖注入1.5.1 背景介绍 设计模式中,尤其是结构型模式很多时候解决的就是对象间的依赖关系, ...

  6. 第五章 编码/加密——《跟我学Shiro》

    转发地址:https://www.iteye.com/blog/jinnianshilongnian-2021439 目录贴:跟我学Shiro目录贴 在涉及到密码存储问题上,应该加密/生成密码摘要存储 ...

  7. 如何禁用maven下载进度指示?

    方法 mvn -B ..或者mvn --batch-mode ...

  8. dos下通过命令访问url网址

    psexec.exe工具: https://blog.csdn.net/feier7501/article/details/8841756 https://www.cnblogs.com/boltki ...

  9. demo rabbitmq topic(主题模式),fanout(广播模式),轮询分发,确认接收Ack处理

    //durable = true 代表持久化 交换机和队列都要为true ,持久代表服务重启,没有处理的消息依然存在 //topic 根据不同的routkey 发送和接收信息 //fanout 广播模 ...

  10. Anaconda是什么?Anconda下载安装教程(1)

    一.如果从事Python开发,配置环境需要安装两个包: 第一个安装开发工具,俗称IDE : 推荐使用 Pycharm 第二个安装开发工具包: Anaconda ps:Windows 下 Pycharm ...