第三十二天 框架的启蒙之路 —Struts2的思考

             6月21日,晴。“明月别枝惊鹊,清风半夜鸣蝉。稻花香里说丰年。听取蛙声一片。“

        因为有了Struts1,俺们了解了开源框架;因为有了Struts2,俺们又知道了两个开源框架还可以合为一体。惊讶

             写一个常见的struts2的应用热热身大笑架框架,就要先搭一个架子结构,然后再抹灰砌砖...

             1、搭建Struts 2开发环境

               进入Struts 2的官方网站http://struts.apache.org/下载struts-2.3.16.3-all.zip。Struts 2安装包只是一个简单的压缩文件,解压即可。

            2、创建一个Web项目,导入Struts 2类库             

        在新建立的项目基础上开始配置Struts2的功能,添加Struts 2的JAR包。在Struts 2安装目录下的lib子目录中,有很多JAR包,不同的应用需要的JAR包是不同的。对于初学者比较简单的做法是直接从解压缩的struts-2.3.16.3-all\struts-2.3.16.3\apps\struts2-blank\WEB-INF\lib目录中的所有.jar文件拷贝到新建的项目的lib目录下


           3、 在web.xml文件中配置FilterDispatcher

          编辑WebRoot\WEB-INF\web.xml文件,添加FilterDispatcher过滤器的配置,web.xml的完整代码如下。初学者同样可以参考struts-2.3.16.3\apps\struts2-blank\WEB-INF文件夹下面的web.xml文件。         

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>Struts2_01</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<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>

</web-app>

         <filter>指定了需要加载的Struts 2核心控制器org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,而<filter-mapping>使用通配符“/*”来拦截所有的URL请求,保证了用户请求都被Struts 2接收处理。

               4、编写Action类-LonginAction.java

package edu.eurasia.action;

public class LonginAction {
	private String username;
	private String password;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	/*public String execute() throws Exception{
		return "success";
	}*/
	
	public String detail() throws Exception{
		return "success";
	}
	
}
         在LonginAction类中,没有继承任何类,也没有实现任何接口,是一个标准的Java类。

          5、视图资源——编写请求login.jsp和结果页面result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ 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>
	<s:form action="login" namespace="/mystruts">
		<s:textfield key="username" />
		<s:password key="password" />
		<s:submit />
	</s:form>

	 
	<!-- <form action="mystruts/login" method="post"  >
		username: <input type="text" name="username" /><br/> 
		password: <input type="password" name="password" /> <br /> 
		<input type="submit" name="submit" />
	</form> -->
	
</body>
</html>
       结果页面result.jsp
<!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>
    username:${username}<br/>
    password: ${password}    
</body>
</html>

       6、配置struts.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="struts2" namespace="/mystruts" extends="struts-default">
       		<action name="login"  class="edu.eurasia.action.LonginAction"  method="detail">
			<result name="success">/result.jsp</result>
		</action>
	</package>
</struts>
            7、运行结果和项目结构

      



          思考:以上代码,比较常见,大多数初学者都能模仿-配置-运行,得到想要的结果。可是,很多人总感觉”不识庐山真面目“,到底用户名和密码这两个数据是如何传输的,百思不解,徒有”只缘身在此山中“的叹息。

          下面,我们不妨解析一下数据如何注入的,又是如何呈现的。疑问

         一、分析结果页面result.jsp          

        1、  结果使用EL表达式,使JSP写起来更加简单。除了上述一种写法,你可能还看到:

          第二种方式:          

      username: ${requestScope.username}  <br/>
      password: ${requestScope.password}  
           第三种方式:
      username: ${param.username}  <br/>
      password: ${param.password}  
          还可以不使用EL表达式,可以这样写:

     第一种方式:

   username:  <%=request.getParameter("username") %><br/>
   password: <%=request.getParameter("password") %> 
           第二种方式:  
      username:  <%=request.getAttribute("username") %><br/>
      password: <%=request.getAttribute("password") %>  

         上述方法,均可得到相同结果。可以看出,实际上,

      ${param.username} 等价于 request.getParamter("username"),这两种方法一般用于服务器从页面或者客户端获取的内容。

  ${requestScope.username} 等价于 request.getAttribute("username"),一般是从服务器传递结果到页面,在页面中取出服务器保存的值。

      那么,写成如下方式,行不行?

    username: ${sessionScope.username}  <br/>
    password: ${sessionScope.password}  
         试一下,好像不行。原因是应用范围不对:

      requestScope是EL表达式的隐含对象,和变量作用域差不多。EL表达式的隐含对象包括:    

       pageScope,requestScope,sessionScope,applicationScope

      例如:${message}

   EL会依次到pageScope,requestScope,sessionScope,applicationScope中寻找,直到找到为止。   

  如果写成${requestScope.message}的形式,将会缩小范围只在requestScope中查找message。
      表示变量的作用域,一共4种:
           pageScope:表示变量只能在本页面使用。
           requestScope:表示变量能在本次请求中使用。
          sessionScope:表示变量能在本次会话中使用。
          applicationScope:表示变量能在整个应用程序中使用。
       总结:在MVC体系结构中,JSP页面只是用来显示数据,但JSP脚本中的表达式功能不够强大,它不能直接对隐式对象中某对象的属性进行显示,需要配合Scriptlet才能显示数据,很是麻烦,如果在JSP页面中使用EL表达式将大大简化JSP页面中的Java代码,在配合JSP标准动作,JSTL,可达到真正的JSP无脚本。

       2、如果result.jsp写成如下方式,还想得到正确结果,有没有别的方法?

        username: ${sessionScope.username}  <br/>
        password: ${sessionScope.password}  
        当然有了,需要改动的是LonginAction.java文件的detail()方法,改动如下:
public String detail() throws Exception{
		ActionContext.getContext().getSession().put("username", username);
		ActionContext.getContext().getSession().put("password", password);
		return "success";
	}
     ActionContext.getContext().getSession()是webwork取session的方式,把用户名和密码暂时存放到HttpSession里,以前servlet里是通过request.getSession()的方式取的。put是方法,参数是(key, value) key 是String, value是Object类型。整个过程像以前的session.setAttribute() 方法。
    那么,result.jsp改回如下方式,LonginAction.java怎么改?
    username:${username}<br/>
    password: ${password}    
     LonginAction改动如下:
         ActionContext.getContext().put("username", username);
         ActionContext.getContext().put("password", password);		
	 return "success"
        ActionContext.getContext()取得HttpServletRequest对象,也就是org.apache.struts2.ActionContext类,通过它的静态方法getContext()获取当前Action的上下文对象。 put("username", username)相当于request.setAttribute("username", username)。
      result.jsp也可以这样写:
   username:  <%=ActionContext.getContext().get("username") %> <br/>
   password:  <%=ActionContext.getContext().get("password") %>
      不过,要import="com.opensymphony.xwork2.ActionContext"%
   总结:  ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如session, parameters, locale等。 ActionContext本身的数据结构是映射结构,即一个Map,用key来映射value。所以使用者完全可以像使用Map一样来使用它,或者直接使用Action.getContextMap()方法来对Map进行操作。
         3、使用OGNL访问ValueStack
       Struts2会将Action中的属性存放到ValueStack对象中,在通过Action转发的页面中,我们可以通过Struts2的标签<s:property value="Ognl表达式"/>来输出这些值。
username: <s:property value="username"/><br/>
password: <s:property value="password"/>
<s:debug></s:debug> 
       Struts2提供了一个非常好的调试方法,就是在页面上添加一个debug标签,它会自动帮我们将一些信息显示在页面上。

      但是这样得到的值却仅限于输出显示,不能进行进一步的操作,那么我们应该怎样得到ValueStack中的值又能对它进行其它操作呢?
           Struts2是将Action中的属性全部封装在一个叫做struts.valueStack的请求属性中,然后我们就可以通过下面的代码来获取这些值了:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.opensymphony.xwork2.util.*,com.opensymphony.xwork2.ActionContext"%>
<% 
   ValueStack vs =(ValueStack)request.getAttribute("struts.valueStack");
   String username = (String)vs.findValue("username");
   String password = (String)vs.findValue("password");
%>
username:<%=username %><br/>
password:<%=password %> 
<s:debug></s:debug> 
        或者使用ActionContext.getContext().getValueStack()
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.opensymphony.xwork2.util.*,com.opensymphony.xwork2.ActionContext"%>
<% 
  ValueStack vs = ActionContext.getContext().getValueStack();
   String username = (String)vs.findValue("username");
   String password = (String)vs.findValue("password");
%>
username:<%=username %><br/>
password:<%=password %> 
<s:debug></s:debug> 
          总结:<s:property value="username"/>,标签的value属性的值就是使用的ognl,它没有任何前缀,就表示直接访问值栈。访问到值栈过后,会按照从栈顶到栈底的顺序,寻找第一个匹配的对象,那就会找到Action中的username属性,然后就取到值了。
         4、 使用OGNL访问ActionContext

      在OGNL中,可以通过符号“#”来访问ActionContext中除了值栈之外的各种值,典型如:

  • #parameters:当前请求中的参数,对应request.getParameter(username)
  • #request:请求作用域中的属性,对应request.getAttribute(username)
  • #session:会话作用域中的属性,对应session.getAttribute(username)
  • #application:应用程序作用域的属性
  • #attr:按照页面page、请求request、会话session和应用application的顺序,返回第一个符合条件的属性。

在引用的时候,需要加上前缀“#”,并指定范围,然后写出要引用哪个属性,形如:“#paramters.username”。

     username: <s:property value="#request.username"/><br/>	
	password: <s:property value="#request.password"/> 
	<s:debug></s:debug> 
            相当于<%=request.getAttribute("username") %>

         

      





Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值