在学习Struts2之前先来了解一下什么是Struts2:
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。
---------摘自百度百科
Struts2 与Struts1的区别:
struts2相对于struts1来说简单了很多,并且功能强大了很多,我们可以从几个方面来看:
- 从体系结构来看:struts2大量使用拦截器来出来请求,从而允许与业务逻辑控制器 与 servlet-api分离,避免了侵入性;而struts1.x在action中明显的侵入了servlet-api.
- 从线程安全分析:struts2.x是线程安全的,每一个对象产生一个实例,避免了线程安全问题;而struts1.x在action中属于单线程。
- 性能方面:struts2.x测试可以脱离web容器,而struts1.x依赖servlet-api,测试需要依赖web容器。
- 请求参数封装对比:struts2.x使用ModelDriven模式,这样我们 直接 封装model对象,无需要继承任何struts2的基类,避免了侵入性。
- 标签的优势:标签库几乎可以完全替代JSTL的标签库,并且 struts2.x支持强大的ognl表达式。
当然,struts2和struts1相比,在 文件上传,数据校验 等方面也 方便了好多。在这就不详谈了。
搭建Struts2开发环境
Struts2官网:
https://struts.apache.org/
Struts2相关jar包下载地址:
http://struts.apache.org/download.cgi
使用Eclipse的同学可以在这里选择下载所有的jar包文件,将其导入到项目中去,这样准备工作就完成了。
接下来演示使用IDEA来搭建Struts2开发环境
首先打开IDEA,选择新建工程
选择Java EE中的Struts2.注意这里假如本地没有lib包的话会自动从网上下载,也可以选择稍后设置。
选择next
点击Finish即可
相关的依赖文件会自动从网上下载
等待依赖文件下载完成后,项目就搭建完成
其中:
自动生成的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>
</struts>
介绍一下其中的主要标签:
自动生成的web.xml文件内容为:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<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>
Struts2 Hello World程序创建
先介绍一个演示程序所完成的功能:
我们在一个表单中进行登录界面的编写,但不同于以往的登录界面,我们这次使用Struts2来完成这些功能。
首先在web文件夹下编写对应的jsp界面
index.jsp
<%--
Created by IntelliJ IDEA.
User: icarus
Date: 2016/7/2
Time: 12:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<title>登录</title>
</head>
<body>
<form method="post" action="<%=path%>/new/login.action">
用户名:<input type="text" name="userName"><br/>
密码:<input type="password" name="passWord"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
登录成功界面success.jsp
<%--
Created by IntelliJ IDEA.
User: icarus
Date: 2016/7/2
Time: 12:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
登录成功
</body>
</html>
登录失败界面fail.jsp
<%--
Created by IntelliJ IDEA.
User: icarus
Date: 2016/7/2
Time: 12:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
登录失败
</body>
</html>
接下来是对应的Action功能编写LoginAction.java
package cn.lovepi.chapter01.action;
/**
* Created by icarus on 2016/7/2.
* 创建表单数据验证类
*/
public class LoginAction {
// 表单属性
private String userName;
private String passWord;
/**
* 执行表单验证操作
* @return 验证状态
*/
public String execute(){
if (userName.equals("wangxin")&&passWord.equals("123456")){
return "success";
}else {
return "fail";
}
}
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;
}
}
接下来便是Struts2的核心所在,即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>
<!--bean 标签,用于创建一个Java Bean实例-->
<!--constant 标签,用于Struts2默认行为标签-->
<!--package 标签,包标签 用于区分不同的请求文件的标签,比方说网站前台与后台的请求-->
<!--include 标签,用于引入其他的xml配置文件-->
<!--接下来详细介绍constant的主要用法-->
<!--配置web默认编码集,相当于HttpServletRequest.setCharacterEncoding用法
但是这样设置相当于写在了过滤器中,以后所有的访问都不需要在手动指定编码格式-->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!--默认的Struts2的请求后缀是.action 假如我们不配置此项属性的话,Struts2之后拦截
后缀为action的请求,在配置此项之后便会拦截action/do后缀的请求-->
<constant name="struts.action.extension" value="action,do"/>
<!--设置浏览器是否缓存静态内容,默认为true,在我们开发阶段建议关闭,
防止修改后测试不到-->
<constant name="struts.serve.static.browserCache" value="false"/>
<!--struts2配置文件重新修改后,系统是否自动重新加载配置文件,默认为false。
开发阶段建议配置为true,便于开发。-->
<constant name="struts.configuration.xml.reload" value="true"/>
<!--开发模式下使用,可以打印出更加详细的错误信息-->
<constant name="struts.devMode" value="true"/>
<!--默认视图主题-->
<constant name="struts.ui.theme" value="simple"/>
<!--接下来详细介绍package的主要用法-->
<!--name:包名,用于被别的包调用或继承。
namespace:命名空间,选填,url连接必须加入/new/action.***
extends:继承,Struts2中的所有包默认继承自struts-default包-->
<package name="test" namespace="/new" extends="struts-default">
<!--action相当于以前的servlet的概念,对应一个请求的name为请求的url地址。
也就是说我们想要方法我们所配置的action的话,其访问路径为:
localhost:8080/项目名称/包(命名空间)/login.do(按照上面的配置)
-->
<action name="login" class="cn.lovepi.chapter01.action.LoginAction">
<!--配置返回结果对应的跳转页面-->
<result name="success">/chapter01/success.jsp</result>
<result name="fail">/chapter01/fail.jsp</result>
</action>
</package>
</struts>
将程序发布到tomcat中去,观察运行结果
可以看到只需配置struts.xml文件而不用像以前那样进行servlet的编写从而进行请求转发到对应界面。
极大的降低了程序之间的耦合度同时方便开发。
那么我们便来分析下在这个例子中程序走向流转
首先介绍下Http请求的流转过程:
1.可以看到一个Http请求首先会被web.xml所处理,在web.xml中首先会被过滤器所拦截
2.通过Struts2所设置的默认过滤器便将请求转发到struts.xml中去处理
3.我们在struts.xml中配置了相关的前置拦截器,那么前置拦截器便会对所设置的请求进行处理(例如我们所设置的.do请求以及默认的.action请求)
4.然后根据设置的url将请求转到所对应的Action类中去,在Action类中进行逻辑处理并返回一个字符串标志
5.假如配置了对应的后置拦截器则会转到后置拦截器的业务处理逻辑中去。
6.接下来struts.xml便会根据返回的字符串从而跳转到相应的结果界面。
7.进而显示给用户所需的界面。
而在我们上面的那个例子中的数据流转又是如何的呢,那么我们便来看一看
这样,我们就完成了一个简单的Struts2的演示程序。