• 上一章节末((三)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. 解决用root用户及密码可以直接登陆某LINUX系统,但是用ssh登陆,系统却总是提示密码不对

    引用 vi /etc/ssh/sshd_config 将PermitRootLogin项改为yes service sshd restart 重启sshd服务即可

  2. ST (Sparse Table:稀疏表)算法

    1541:[例 1]数列区间最大值 时间限制: 1000 ms         内存限制: 524288 KB提交数: 600     通过数: 207 [题目描述] 输入一串数字,给你 MM 个询问 ...

  3. 目录:JAVA

    收藏: Java:类与继承

  4. 简易的CRM系统案例之SpringMVC+JSP+MySQL+hibernate框架版本

    继续对上一版本进行改版,变成SpringMVC框架 简易的CRM系统案例之易的CRM系统案例之JSP+MySQL+SSH框架版本 src/spring.xml <?xml version=&qu ...

  5. WGS84 2 GCJ-02

    #include ; ) { x=-x; ff=; } cc=) ff=; ) ff=; } x=tt; ss=x; s2=x; tt=tt*tt; s2=s2*tt; ss=ss-s2* ) ss= ...

  6. QML发布程序

    如果是在windows系统下,则最终打包成exe windeployqt  xxx.exe  -qmldir  C:\Qt\Qt5.9.6\5.9.6\mingw53_32\qml 注意使用Qt自己的 ...

  7. 服务器(三):利用github的webhooks实现自动部署

    实现自动部署的关键就是利用github的webhooks,我们在github建立一个项目之后,在项目主页点击Settings,看到Webhooks点击打开可以添加一个链接,这里的意思是,github可 ...

  8. iOS-self.用法

    关于self.用法的一些总结 2010-01-10 21:46 最近有人问我关于什么时候用self.赋值的问题, 我总结了一下, 发出来给大家参考. 有什么问题请大家斧正. 关于什么时间用self. ...

  9. iOS算法题

    1兔子算法题 兔子可以跳一步2步或者3步,问跳到100有多少种跳法? // 兔子可以跳一步2步或者3步 // 问跳到100有几种跳法 /* 分析1 两个变量,X*2+Y*3=100. X最大为50,X ...

  10. ES SQL使用说明文档

    ES SQL使用说明文档 一.Elasticsearch术语介绍 l  接近实时(NRT): Elasticsearch 是一个接近实时的搜索平台.这意味着,从索引一个文档直到这个文档能够被搜索到有一 ...