Struts2项目实例

Java web动态编程技术,经历了Model1和Model2时代。

Model1时代:整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出响应,用少量的JavaBean来处理数据库连接访问等操作。Model1的局限性非常明显,JSP页面同时担任View和Controller两种角色,将页面表现和逻辑处理混杂在一起,代码重用性极低,增加了扩展和维护难度。

Model2时代:已经采用了MVC的设计。在Model2架构中,Servlet作为Controller,负责接收用户请求,只包含控制逻辑,然后调用后端来进行具体的逻辑处理。最后转发到相应的JSP页面负责显示。

Model2(Servlet+JSP+JavaBean项目示例

Struts是开源软件,使开发者能更深入的了解其内部实现机制。Struts开放源码框架的创建是为了使开发者在构建基于java Servlet和JavaServer Pages(jsp)技术的Web应用时更加容易。Struts框架为开放者提供了一个统一的标准框架,通过使用Struts作为基础,开发者能够更专注于应用程序的商业逻辑。Struts框架本身是使用Java Servlet和JavaServer Pages技术的一种Model-View-Controller(MVC)实现。

Struts2是基于MVC设计模式的流行和成熟的Web应用程序框架。Struts2并不只是Struts 1下一个版本,但它是一个完全重写的Struts架构。Struts2使用拦截器作为增强处理,以用户的逻辑控制器为目标,创建一个控制器代理,控制器代理回调业务控制器的execute方法处理用户请求,该方法的返回值决定struts2将怎样的视图资源呈现给用户。

Struts2 框架特性
  • POJO形式和POJO动作 - 已经摆脱了Struts2的动作表单的Struts框架的一个组成部分。Struts2可以使用任何的POJO接收的形式输入。同样的,你现在可以看到任何POJO的Action类。
  • Tag支持 - Struts2的形式提高了标签的新标签让开发人员写更少的代码。
  • AJAX支持- Struts2中已经认识到了Web2.0技术,并整合到产品中AJAX支持创建AJAX的标签,该功能非常相似的标准Struts2的标签。
  • 容易整合 - 与其他框架如Spring,Tiles和SiteMesh的整合是现在更容易与各种集成Struts2。
  • 模板支持 - 支持生成使用模板。
  • 插件支持 - 核心Struts2行为,可以加强和扩大使用插件。大量的插件可供Struts2。
  • 概要分析- Struts2的提供集成的配置,调试和分析应用程序。此外,Struts还提供了内置调试工具的帮助下,集成调试。
  • 标签修改容易 - 在Struts2标签标记,可以调整使用FreeMarker模板。这并不需要JSP或Java知识。基本的HTML,XML和CSS知识是不够的修改的标签。
  • 提升更少的配置 - Struts2的促进更少的配置与用于各种设置的帮助下,使用默认值。你没有的东西,除非它偏离由Struts2的默认设置的配置。

Struts2请求生命周期:

  • 用户发送请求到服务器,用于请求对某些资源。
  • 核心控制器StrutsPrepareAndExecuteFilter根据请求决定是否调用相应的Action。
  • Struts2内置的拦截器链会自动对请求进行一些操,如验证,文件上传等。
  • 回调Action的execute方法,执行操作。
  • 配置拦截器做任何后期处理,如果需要的话。如Action会将处理结果存入stack Context中,并返回字符串,核心控制器根据字符串跳转到指定的视图资源。
  • 视图资源会读取Stack Context中的信息,向用户生成响应数据。

Struts2的优点:

  • Struts2实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现。
  • Struts2有丰富的标签可以用,Struts的标记库(Taglib),能大大提高开发效率。
  • Struts2的页面导航。页面导航将是今后的一个发展方向,事实上,页面导航使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着非常大的好处。尤其是当新一批开发者接手这个项目时,这种优势体现得更加明显。
  • Struts2提供Exception处理机制。
  • Struts2数据库链接池管理。
  • Struts2支持I18N。

Struts2的缺点:

  • 转到展示层时,需要配置forward。每一次转到展示层,大多数都是直接转到jsp,而涉及到转向,需要配置forward。每次修改配置之后,都需要重新部署整个项目,并且如果使用tomcat服务器,还必须重新启动服务器。
  • Struts2的Action必需是线程安全,它只允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
  • 测试不方便。Struts2的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,很难实现单元测试。不过Struts2 JUnit插件的StrutsTestCase可以实现它的单元测试。
  • 类型的转换。Struts2的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。
  • 对Servlet的依赖性过强。Struts2处理Action时必需要依赖ServletRequest和ServletResponse,所有它摆脱不了Servlet容器。
  • 前端表达式语言方面。Struts2集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。
  • 对Action执行的控制困难。Struts2创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。
  • 对Action执行前和后的处理。Struts2处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。
  • 对事件支持不够。在Struts2中,实际是一个表单Form对应一个Action类(或DispatchAction),即在Struts2中实际是一个表单只能对应一个事件,Struts2这种事件方式称为application event,application event和component event相比是一种粗粒度的事件。
  • Struts2重要的表单对象ActionForm是一种对象,它代表了一种应用,这个对象中至少包含几个字段,这些字段是Jsp页面表单中的input字段,因为一个表单对应一个事件,所以,当我们需要将事件粒度细化到表单中这些字段时,也就是说,一个字段对应一个事件时,单纯使用Struts就不太可能,当然通过结合JavaScript也是可以实现的。

Struts2环境的搭建

1. 开发环境: Eclipse Luna Release (4.4.0), JDK1.8, Maven(apache-maven-3.5.4), Struts(2.5.14.1), Tomcat(tomcat-8)

2. 创建Maven Web项目

3. 配置Struts2依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>angelia</groupId>
    <artifactId>strutsmaven</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>strutsmaven Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>

        <struts2.version>2.5.14.1</struts2.version>
        <log4j2.version>2.10.0</log4j2.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>${struts2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>strutsmaven</finalName>
    </build>
</project>
4. 配置Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Basic Struts2</display-name>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

5. 创建log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Appenders>
		<Console name="STDOUT" target="SYSTEM_OUT">
			<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Logger name="com.opensymphony.xwork2" level="debug" />
		<Logger name="org.apache.struts2" level="debug" />
		<Root level="warn">
			<AppenderRef ref="STDOUT" />
		</Root>
	</Loggers>
</Configuration>
6.创建view,index.jsp, login.jsp, error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>首页</title>
</head>
<body>

	欢迎来到Angelia的网站
	<hr>
	<c:if test="${username==null}">
		<a href="${pageContext.request.contextPath}/gologin.action">登录</a>
	</c:if>
	<c:if test="${username!=null}">
 		欢迎:${username}
        <a href="${pageContext.request.contextPath}/logout.action">注销</a>
	</c:if>

</body>
</html>
<%@ 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>登录界面</title>
</head>

<body>
	<form action="login" method="post">
		<table>
			<tr>
				<td>用户名:</td>
				<td><input type="text" name="username" /></td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="text" name="password" /></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="登录" />
				<input type="reset" value="重置" /></td>
			</tr>
		</table>
	</form>
</body>
</html>
<%@ 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>错误页</title>
</head>

<body>
	<p>操作失败</p>
</body>
</html>
7. 创建Action
public class UserAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	public String execute(){
		return SUCCESS;
	}

	public String login(){
		HttpServletRequest request = ServletActionContext.getRequest();

		String username = request.getParameter("username");
		String password = request.getParameter("password");

		if("angelia".equals(username) && "123456".equals(password)){
			request.setAttribute("username", username);
			return SUCCESS;
		}else{
			return ERROR;
		}
	}

	public String logout(){
		HttpServletRequest request = ServletActionContext.getRequest();
		request.removeAttribute("username");
		return SUCCESS;
	}
}

8. 配置struts.xml

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

<struts>
	<constant name="struts.devMode" value="true" />
	<package name="strutsmaven" extends="struts-default">
		<action name="index">
			<result>/index.jsp</result>
		</action>

		<action name="gologin" class="angelia.struts.action.UserAction">
			<result name="success">login.jsp</result>
			<result name="error">error.jsp</result>
		</action>
		<action name="login" class="angelia.struts.action.UserAction"
			method="login">
			<result name="success">index.jsp</result>
			<result name="error">error.jsp</result>
		</action>

		<action name="logout" class="angelia.struts.action.UserAction"
			method="logout">
			<result name="success">index.jsp</result>
			<result name="error">error.jsp</result>
		</action>
	</package>

</struts>

9. 启动项目:http://localhost:8080/strutsmaven/


10. 表单验证form-validation,Struts2有两种方法进行表单验证。一是action class添加validate方法,即validate()。二是使用Struts 2的XML,在Action对应路径下src/main/resources/angelia/struts/action生成ActionClassName-validation.xml文件。

validate method

public void validate(){
      if (username.length() == 0) {
          addFieldError("username", "First name is required.");
      }
}

<s:form action="login">
    <s:textfield name="username" label="用户名" />
    <s:password name="password" label="密码"/>
    <s:submit/>
</s:form>

XML Validator, 创建UserAction-validation.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
    <validator type="requiredstring">
        <param name="fieldname">username</param>
        <message>Username is required from XML.</message>
    </validator>
</validators>

11. 添加Message Resource文件,在src/main/resources/angelia/struts/action添加ActionClassName.properties。而且 properties文件必须放在和Action class相同的包下。为了能使用properties文件里的key attribute, 这个要展示的页面必须是从刚执行的Struts Action class跳转来的。

创建UserAction.properties

username=用户名prop

修改jsp

<%-- <s:textfield name="username" label="用户名" /> --%>
<s:textfield key="username"  />
修改struts.xml
<action name="loginInput" class="angelia.struts.action.UserAction" method="input">
    <result name="input">/newlogin.jsp</result>
</action>

12 Package Level Properties和Global Properties

创建package.properties在src/main/resources/angelia/struts/action下,由此包下的所有Action跳转过去的页面都可使用package.properties里面的资源。

在文件src/main/resources下创建myglobal.properties文件。

struts.xml文件添加:<constant name="struts.custom.i18n.resources" value="myglobal" />







猜你喜欢

转载自blog.csdn.net/u014010512/article/details/80880478