Struts2

[b]一、Struts2概述[/b]
Struts2 是Apache软件基金会(ASF)赞助的一个开源项目,使用Struts2的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,Struts2是一个不错的选择。

[b]二、Struts2工作原理[/b]
[img]http://dl2.iteye.com/upload/attachment/0094/9553/3185d01f-1763-3b9f-b72d-5266492c524b.jpg[/img]
如图,Struts2工作原理大概分为以下几个步骤:
1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求。
2.这个请求经过一系列的过滤器(Filter)(ActionContextCleanUp,SiteMesh,etc等)。
3.接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求调用那个Action。
4.FilterDispatcher将控制权委派给ActionProxy,ActionProxy通过Configuration Manager读取框架的配置文件,然后创建一个ActionInvocation实例。
5.ActionInvocation调用Action,Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。

[b]三、Struts2相对于Struts1的改进[/b]
[b]1.在Action的实现方面[/b]
Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
[b]2.线程模型方面[/b]
Struts1的Action是单实例的,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。
[b]3.Servlet依赖方面[/b]
Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。
[b]4.封装请求参数[/b]
Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
[b]5.表达式语言方面[/b]
Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。绑定值到视图技术
Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
[b]6.类型转换[/b]
Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。
[b]7.Action执行控制的对比[/b]
Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。

[b]四、Struts2开发示例[/b]
[b]1. Struts2的下载[/b]
官方下载地址:http://struts.apache.org/download.cgi
Struts2完整版结构如下:apps(应用示例),docs(帮助文档,API),lib(核心类库),src(全部源码)

[b]2. 导入struts2核心类库到项目[/b]
基本包包括:antlr-2.7.2.jar,commons-fileupload-1.3.jar,commons-io-2.0.1.jar,commons-logging-1.1.3.jar,commons-lang3-3.1.jar,freemarker-2.3.19.jar,javassist-3.11.0.GA.jar,ognl-3.0.6.jar,struts2-core-2.3.15.3.jar,
xwork-core-2.3.15.3.jar,如需使用Struts2的更多特性,则需导入其它jar包

[b]3. 在web.xml中配置Struts2的核心Filter[/b]

<!-- 定义Struts2的核心Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- 让Struts2的核心Filter拦截所有请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

[b]4. 创建登陆页面login.jsp,测试Struts2[/b]

<script type="text/javascript">
function regist(){
//获取页面的第一个表单
targetForm = document.forms[0];
//动态修改表单的action属性
targetForm.action = "regist";
}
</script>
<body bgcolor="pink">
<center>
用户登陆<br><hr>
<form action="login">
账 号:<input type="text" name="username"><br>
密 码:<input type="text" name="password"><br>
<input type="submit" value="登陆">
<input type="submit" value="注册" οnclick="regist();">
</form>
</center>
</body>

[b]5. 为Struts2添加配置文件struts.xml[/b]

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<!-- 指定Struts 2配置文件的根元素 -->
<struts>
<!-- 指定全局国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 指定国际化编码所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 所有的Action定义都应该放在package下 -->
<package name="userManager" extends="struts-default">
<!-- 不配置method属性,交给默认的execute()方法处理 -->
<action name="login" class="test.action.LoginAction">
<!-- 定义三个逻辑视图和物理资源之间的映射 -->
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
<!-- 配置method属性,交给regist()方法处理 -->
<action name="regist" class="test.action.LoginAction" method="regist">
<result name="success">/welcome.jsp</result>
</action>
</package>
<!-- 导入其它完整的配置文件 -->
<include file="struts-xxx.xml"></include>
</struts>

[b]6. 编写Action处理类BaseAction.java,LoginAction.java[/b]

/// 1.BaseAction
package test.action;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport {

private transient HttpServletRequest request = null;
private transient HttpServletResponse response = null;
private transient ServletContext servletContext = null;
private transient HttpSession session = null;

public void setRequest(HttpServletRequest request) {
this.request = request;
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public void setSession(HttpSession session) {
this.session = session;
}
public HttpServletRequest getRequest(){
if(request != null){
return request;
}
return ServletActionContext.getRequest();
}
public HttpServletResponse getResponse(){
if(response != null){
return response;
}
return ServletActionContext.getResponse();
}
public ServletContext getServletContext(){
if(servletContext != null){
return servletContext;
}
return ServletActionContext.getServletContext();
}
public HttpSession getSession(){
if(session != null){
return session;
}
return getRequest().getSession();
}
}


/ 2. LoginAction
package test.action;

public class LoginAction extends BaseAction{
//定义封装请求参数的username和password属性
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;
}
//注册Action
public String regist() throws Exception {
System.out.println(this.getRequest().getAttribute("username"));
this.getRequest().setAttribute("username", "regist");
return SUCCESS;
}
//默认的登陆Action
public String execute() throws Exception {
// 1. 通过request对象得到表单的值
System.out.println(this.getRequest().getParameter("username"));
// 2. 直接通过getter和setter得到表单的值
if (getUsername().equals("a")&& getPassword().equals("a")){
// 3. 设置、得到session的值
this.getSession().setAttribute("username", "ok");
System.out.println(this.getSession().getAttribute("username"));
// 4. 设置响应的字符串
this.getResponse().setCharacterEncoding("UTF-8");
this.getResponse().getWriter().print("ccccc");
return SUCCESS;
} else {
return ERROR;
}
}
}


[b]7. 其它跳转页面welcome.jsp[/b]

<body>
登陆成功!<%=request.getAttribute("username")%><br>
<a href="login.jsp">退出</a><hr>
</body>

[b]五、Struts2的文件上传和下载[/b]
[b]Struts2的文件上传:[/b]
[b]1. 测试文件上传页面upload.jsp[/b]
此处使用Struts2标签来生成上传文件的表单,为了让浏览器采用二进制数据的方式把数据发送到服务器,我们必须把表单的method设置为POST,将enctype设置为multipart/form-data。jsp代码如下:

<body>
<s:form action="uploadPro" method="post" enctype="multipart/form-data">
<s:file name="upload" label="选择文件"/><br />
<s:submit value="上传"/>
</s:form>
</body>

[b]2. 实现文件上传的Action(UploadAction.java)[/b]
Action实现类其实非常简单,只需要定义三个属性接收文件参数即可,一是类型为File的xxx封装文件内容,二是String类型的xxxFileName封装文件名,三是String类型的xxxContentType封装文件类型。代码如下:
package test;
import com.opensymphony.xwork2.ActionSupport;
import java.io.*;
public class UploadAction extends ActionSupport{
//封装上传文件域
private File upload;
//封装上传文件类型
private String uploadContentType;
//封装上传文件名
private String uploadFileName;
public void setUpload(File upload) {
this.upload = upload;
}
public File getUpload(){
return (this.upload);
}
public void setUploadContentType(String uploadContentType){
this.uploadContentType = uploadContentType;
}
public String getUploadContentType(){
return (this.uploadContentType);
}
public void setUploadFileName(String uploadFileName){
this.uploadFileName = uploadFileName;
}
public String getUploadFileName(){
return (this.uploadFileName);
}
@Override
public String execute() throws Exception{
//将文件写入服务器,没有此文件时新建
File file = new File("h:\\AAA\\"+getUploadFileName());
FileOutputStream fos = new FileOutputStream(file);
FileInputStream fis = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0){
fos.write(buffer , 0 , len);
}
fos.close();
return SUCCESS;
}
}


[b]3. 配置文件上传的Action(struts.xml)[/b]

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="test.UploadAction">
<!-- 配置Struts 2默认的视图页面 -->
<result>/upload.jsp</result>
</action>
</package>
</struts>

4. 实现文件过滤
方法一:直接在Action中判断文件的类型是否为允许类型
方法二:拦截器实现文件过滤,如下:

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="org.crazyit.app.action.UploadAction">
<!-- 配置fileUpload的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 配置允许上传的文件类型 -->
<param name="allowedTypes">image/png,image/gif,image/jpeg</param>
<!-- 配置允许上传的文件大小 -->
<param name="maximumSize">2000</param>
</interceptor-ref>
<!-- 配置系统默认的拦截器 -->
<interceptor-ref name="defaultStack"/>
<!-- 配置Struts 2默认的视图页面 -->
<result>/WEB-INF/content/succ.jsp</result>
</action>
</package>
</struts>

[b]Struts2的文件下载:[/b]
[b]1. 测试文件下载jsp页面[/b]

<body>
<ul><li>下载:<a href="download.action">下载文件</a></li></ul>
</body>

[b]2. 实现文件下载的Action(FileDownloadAction.java)[/b]

package test;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.*;
public class FileDownloadAction extends ActionSupport {
//该属性可以在配置文件中动态指定该属性值
private String inputPath;
//依赖注入该属性值的setter方法
public void setInputPath(String value){
inputPath = value;
}
/*
* 定义一个返回InputStream的方法,该方法将作为被下载文件的入口,
* 且需要配置stream类型结果时指定inputName参数,inputName参数的值就是方法去掉get前缀、首字母小写的字符串
*/
public InputStream getTargetFile() throws Exception {
//ServletContext提供getResourceAsStream()方法返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
}


[b]3. 配置文件下载的Action(struts.xml)[/b]

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<action name="download" class="test.FileDownloadAction">
<param name="inputPath">\images\aaa.jpg</param>
<!-- 配置结果类型为stream的结果 -->
<result name="success" type="stream">
<!-- 指定下载文件的文件类型 -->
<param name="contentType">image/jpg</param>
<!-- 指定由getTargetFile()方法返回被下载文件的InputStream -->
<param name="inputName">targetFile</param>
<param name="contentDisposition">filename="hap.jpg"</param>
<!-- 指定下载文件的缓冲大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
</struts>

[b]六、Struts2返回JSON数据示例[/b]
[b]1. 导包[/b]
除导入Struts2基本包以外还要导入struts2-json-plugin-2.3.15.3.jar

[b]2. 实现Action(JSONExample.java)[/b]
package test;
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import org.apache.struts2.json.annotations.JSON;
public class JSONExample{
//模拟处理结果的属性
private int[] ints = {10, 20};
private Map<String , String> map = new HashMap<String , String>();
private String customName = "顾客";
//封装请求参数的三个属性
private String field1;
//'transient'修饰的属性不会被序列化
private transient String field2;
//没有setter和getter方法的字段不会被序列化
private String field3;
public String execute(){
field2 = "333";
map.put("name", "疯狂Java讲义");
return Action.SUCCESS;
}
//使用注释语法来改变该属性序列化后的属性名
@JSON(name="newName")
public Map getMap(){
return this.map;
}
//customName属性的setter和getter方法
public void setCustomName(String customName){
this.customName = customName;
}
public String getCustomName(){
return this.customName;
}
//field1属性的setter和getter方法
public void setField1(String field1){
this.field1 = field1;
}
public String getField1(){
return this.field1;
}
//field2属性的setter和getter方法
public void setField2(String field2){
this.field2 = field2;
}
public String getField2(){
return this.field2;
}
//field3属性的setter和getter方法
public void setField3(String field3){
this.field3 = field3;
}
public String getField3(){
return this.field3;
}
}


[b]3. 配置Action(struts.xml)[/b]

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<package name="example" extends="json-default">
<action name="JSONExample" class="test.JSONExample">
<!-- 配置类型的json的Result -->
<result type="json">
<!-- 为该Result指定参数 -->
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<!-- 设置只返回Action的map属性 -->
<!-- param name="root">map</param -->
</result>
</action>
</package>
</struts>

[b]4. 测试返回结果[/b]
浏览器输入: http://localhost:8080/TestStrutsJSON/example/JSONExample(项目路径+Action配置文件包名+Action名)测试得到的JSON数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的影城管理系统,源码+数据库+论文答辩+毕业论文+视频演示 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各类信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求做了介绍,并且对系统做了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。 关键词:小徐影城管理系统;Spring Boot框架,MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值