现在的位置: 首页 > 综合 > 正文

1、Struts2概述与MVC模式

2017年11月30日 ⁄ 综合 ⁄ 共 8014字 ⁄ 字号 评论关闭

Struts分为两个主要版本,struts1和struts2,struts2是由webwork2发展而来的

1、Framework概念:将相同类型问题的解决途径进行抽象,抽取成为一个应用框架。这就是Framework。

Framework的体系提供了一套明确的机制,从而让开发人员很容易宽展和控制整个Framework开发上的结构;通常,Framework的结构中都有一个“命令和控制”组件(“command and control” component)

    通过基于请求响应模式的应用Framework,基本上有如下几个表现逻辑结构组成:
    - 控制器(Controller)——控制整个Framework中各个组件的协调工作。
    - 业务逻辑层(Business Logic)——对Framework本身来说,这里仅仅只是概念和几个提供服务的基础组件,真正的实现与客户的业务逻辑接轨,还需要开发人员在Framework上再次扩展。
    - 数据逻辑层(Data Logic ) ——绝大多数应用系统都需要涉及到数据交互,这一层主要包括了数据逻辑和数据访问接口
2、Struts有其自己的控制器(Controller),同时整合了其他的一些技术去实现模型层(Model)和视图层(View)。

Struts的概念和体系结构

    Struts有一组相互协作的类、Servlet以及Jsp TagLib组成。基于Struts架构的web应用程序基本上符合JSP Model2的设计标准,可以说是MVC设计模式的一种变化类型。

3、MVC的概念,MVC结构图

MVC处理过程:

    - 首先控制器接收用户的请求,并决定应该调用哪一个模型来进行处理。
    - 然后模型根据用户请求进行相应的业务逻辑处理,并返回数据。
    - 最后控制器调用相应的视图格式化模型返回的数据,并通过视图呈现给用户,

MVC的优点:

   - 首先,最重要的一点是多个视图能共享一个模型。同一个模型可以被不同的视图重用,大大提高了代码的可重用性。
   - 由于MVC的三个模块相互独立,改变其中一个不会影响其他两个,所以依据这种设计思想能构造良好的松耦合的构件。
   - 此外,控制器提高了应用程序的灵活性和可配置性。控制器可以用来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段

MVC的适用范围

    - 使用MVC需要精心的计划,由于它的内部原理比较复杂,所以你需要花费一些时间去理解它。将MVC运用到你的应用程序,会带来额外的工作量,增加应用的复杂性。
    - 但对于开发存在大量用户界面,并且业务逻辑复杂的大型应用程序,MVC将会使你的软件在健壮性、代码重用和结构方面上一个新的台阶。尽管在最初构建MVC框架时会花费一定的工作量,但从长远角度看,它会大大提高后期软件开发的效率。

4、JavaWeb应用结构的发展

    - 阶段1:JSP是一个独立的、自主完成所有任务的模块
    - 阶段2:JSP Model1
    - 阶段3:JSP Model2

早期的Java Web应用中,JSP文件同时负责生成网页、控制到下一个网页的流程,以及负责业务逻辑,这给Web开发带来一系列问题:
–HTML 和Java 强耦合在一起,JSP 文件的编写者必须既是网页设计者,又是Java 开发者。
–可读性差。
–调试困难。
–不利于维护,更改业务逻辑或数据可能牵涉相关的多个网页。

Model1

Model2:

•JSP负责生成动态网页
•Servlet负责流程控制
•JavaBean负责业务逻辑

5、Struts与Web App的关系
–既然struts叫做webframework,那么其肯定主要基于web层的应用系统开发。按照J2EEArchitecture的标准,struts应当和jsp/servlet一样,存在于webcontainer一层

6、完全手动配置一个Struts程序

    1)下载struts-2.3.14-all.zip,解压缩,四个文件夹:apps,示例,是.war;lib目录,库,struts依赖的一些包,库;docs,文档;src,源代码
    2)myeclipse中创建一个web project
    3)导入jar包,不能将解压出的lib目录下的Jar包都拷入项目的WebRoot/WEB-INF/lib下,多拷贝也能出问题,最小需求包有:commons-fileupload-1.2.2.jar、commons-io-2.0.1.jar、commons-logging-1.1.1.jar、ognl-3.0.6.jar、struts2-core-2.3.14.jar、xwork-core-2.3.14.jar、freemarker-2.3.19.jar
    4)修改web.xml,添加struts过滤器:

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

在这里的filter配置就说明添加上了struts框架,所有的应用都纳入到了struts的管辖范围了。

    5)在src目录下创建struts.xml文件,注意,我们的应用运行时访问的不是src目录下的这个struts.xml,而是WebRoot\WEB-INF\classes目录下的struts.xml,任何src目录下的东西,IDE(myeclipse)都会自动拷贝一份到WebRoot\WEB-INF\classes目录下,为什么不直接在WebRoot\WEB-INF\classes下建呢?因为在IDE中看不到classes目录。

创建好struts.xml后,从apps中的现有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">

这时在写下面内容时,如果没有提示功能,可以这样解决:

      a: 点击window – preferences – 搜索 catalog – add

     b:选择key type为URI

     c:key: http://struts.apache.org/dtds/struts-2.3.dtd    该文件是 struts.xml文件中的,复制即可

     d:location: 对应的dtd文件,位于struts-core包中,解压开,指定相应位置,

      如:D:\Struts2.1.6\soft\struts- 2.1.6 \lib\struts2-core-2.1.6\struts-2.3.dtd

    6)做完以上配置启动服务器,会出现错误,根据错误提示,是缺少jar依赖包,添加了javassist-3.11.0.GA.jar、asm-3.3.jar、asm-commons-3.3.jar、commons-lang3-3.1.jar、commons-lang-2.4.jar、struts2-convention-plugin-2.3.14.jar后启动正常。

    7)编写测试程序

一个登录页面login.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="aas.action">
    	username:<input type="text" name="username"><br>
    	password:<input type="password" name="password"><br>
    	<input type="submit" value="submit">
    </form>
  </body>
</html>

一个结果页面result.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'result.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    username:${requestScope.username } <br>
    password:${requestScope.password }
  </body>
</html>

一个class:LoginAction

package com.cdtax.struts2;



public class LoginAction 
{
	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()
	{
		System.out.println("execute()......");
		return "success";
	}
}

然后配置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" extends="struts-default">
		<action name="aas" class="com.cdtax.struts2.LoginAction">
			<result name="success">/result.jsp</result>
		</action>
	</package>
</struts>

启动服务器,然后访问login.jsp,输入用户名密码提交直接就返回一个result页面。

一开始在配置struts.xml时,将action配置成如:<action name="login" class="com.cdtax.struts2.LoginAction">,login.jsp中的action为login.action,结果死活出不来结果,一直提示No result defined for action com.cdtax.struts2.LoginAction and result success,经过查资料,在struts.xml中action 的name="login"是有冲突的。

至此,手工配置一个struts2.3.14环境完成。

7、通过上面的例子,在struts中,重要的是struts.xml中的配置

由web.xml中的filter可知(url-pattern为 /*),所有的应用都要经过struts的filter,所以login.jsp提交的action,即aas也不例外,对于jsp提交的action,如果没有后缀,filter会自动加上.action后缀,即action="aas" 等同于action="aas.action"

    过程,请求先被struts  filter过滤器接收,然后查找struts.xml,找其中的action,通过name找到匹配的action,然后就进入这个action,就是执行action的class属性指定的类生成的对象来处理请求,这个例子就是com.cdtax.struts2.LoginAction,因为这个类有两个成员变量与页面表单中用户名、密码属性一样,会自动调用对应的get和set方法进行类成员变量设置,并且会将这个信息放到request作用域中,设置完后,执行execute()方法,执行完毕后,转到struts.xml的action的下一步,找到result的name值等于execute()返回值的那一标签,执行其标签内容,就是/result.jsp。

 8、关于struts.xml中的package,也有继承的概念,extends属性,继承某个package,这里是struts-default,这个包在struts2-core-2.3.14.jar中,有一个struts-default.xml文件,这个文件定义了struts如何自动赋值、类型转换等,如果没有继承这个文件,struts就会出错。

9、生成struts的帮助文档:1)新建一个java project ;2)将struts-2.3.14-all\struts-2.3.14\src\core\src\main\java下的org拷贝到新建java project的src下;3)导入依赖的包,主要是struts-2.3.14-all\struts-2.3.14\lib下的包和tomcat的lib下的jsp-api.jar和servlet-api.jar,haiyou一个是velocity-tools-view-1.4.jar,导入后应该没有错误了;4)执行Myeclipse的project下的generate
javadoc,生成帮助文档。

10、关于LoginAction类中成员变量的赋值,不是根据成员变量的名字来进行set,而是根据setXXX方法来进行赋值。实验:

将login.jsp中form加一个age:<input type="text" name="age">,LoginAction中增加private int age;并增加get和set方法,result中增加age:${requestScope.age },这是正常情况,login中输入后,点击提交,结果result.jsp显示出结果,现在将LoginAction中的private int age改为private int aaa,在result.jsp中增加${requestScope.aaa },修改LoginAction中setAge和getAge方法为:public
int getAge()
 {
  return aaa;
 }
 public void setAge(int aaa)
 {
  this.aaa = aaa;
 }

则再次操作,结果age依旧能够显示出来,而aaa则为空;

如果将login.jsp中的age input的name改为aaa,则结果为age:0,aaa为空,因为login.jsp虽然没有传递名字为age的属性,但是LoginAction中有getAge和setAge方法,根据其为int型,设置一个age变量,int没有默认为0,虽然login.jsp传递了一个aaa属性值对,因为LoginAction中没有相应的get和set方法,所以没有设置aaa变量,因此为空。

11、关于服务器启动时命令行提示:有这样三行提示xml的解析顺序

信息: Parsing configuration file [struts-default.xml]
2013-5-13 14:12:02 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
信息: Parsing configuration file [struts-plugin.xml]
2013-5-13 14:12:02 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
信息: Parsing configuration file [struts.xml]

可以看到先是解析了struts-default.xml,这就是struts的默认配置,也是我们自定义的struts.xml所extends的,然后是struts-plugin.xml,这是一些插件的配置文件,格式与struts.xml一样,最后是我们自己定义的struts.xml。

 

 

 

抱歉!评论已关闭.