前言
struts2框架是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互,之前的文章中自定义mvc就是模仿struts2编写的自定义框架,其原理大同小异
struts2基础配置
博主基于maven进行struts2的环境搭建,所以先把依赖和jar配置好,也就是在pom.xml中加入:
<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
由于基于maven,所以resources包下有三个文件:
struts-base.xml
:struts2基础配置文件,所有模块xml继承它实现具体业务层流转控制
struts-hello.xml
:项目模块对应的xml配置,控制对应的action层业务逻辑处理
struts.xml
:struts2核心配置文件,统一加载其他配置文件
可能看到这会疑惑,因为网上很多文章写struts2的xml时,所有的配置都是写在struts.xml一个文件中,但是一个项目如果跳转和处理请求多的话,一个xml写下来到时候出个小bug眼睛都看坏,所以把每个模块分开写更加清晰明了,方便后期维护.
这里就简单做了个登录案例实现简单struts2流程,三个配置文件内容:
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>
<include file="struts-base.xml"></include>
<include file="struts-hello.xml"></include>
</struts>
struts-base.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"></constant>
<!-- 开启自动加载配置文件 -->
<constant name="struts.configuration.xml.reload" value="true"></constant>
<!--
name:包名
exetends:继承
abstract:是否抽象类
namespace:命名空间
-->
<package name="struts-base" namespace="" extends="struts-default" abstract="true">
//通配符
<global-allowed-methods>regex:.*</global-allowed-methods>
</package>
</struts>
struts-hello.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>
<package name="struts-hello" extends="struts-base">
<!-- <action name="helloAction" class="com.xiaoyang.action.HelloStruts" method="execute"></action> -->
<action name="helloAction_*" class="com.xiaoyang.action.HelloStruts"
method="{1}">
<!--
name:跳转路径
type:默认转发
-->
<result name="success" type="dispatcher">/success.jsp</result>
<result name="error" type="dispatcher">/error.jsp</result>
</action>
</package>
</struts>
这里可以看到struts.hello.xml
文件中的方法跳转用了一个{1}
,这是struts2中通配符写法,只需前台传入方法名,加上<global-allowed-methods>regex:.*</global-allowed-methods>
,前台传值:
<form action="helloAction_add.action" method="post">
按照action
节点的name
属性规则配置*(方法名)就可以让struts2自己匹配对应action中的方法执行
action层代码:
package com.xiaoyang.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;
import com.xiaoyang.dao.UserDao;
import com.xiaoyang.entity.User;
/**
* 测试类
*
* @author xiaoyang
*
*/
public class HelloStruts implements ModelDriven<User>,ServletRequestAware,ServletResponseAware{
private UserDao userDao = new UserDao();
private User user = new User();
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
public String execute() {
System.out.println("hello struts2");
return null;
}
private HttpServletRequest req;
private HttpServletResponse resp;
//注入式耦合
@Override
public void setServletResponse(HttpServletResponse response) {
this.resp=response;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.req=request;
}
public String add() throws Exception {
// this.userDao.add(user);
System.out.println(user);
//非注入耦合,和servlet关系紧密
//req=ServletActionContext.getRequest();
//非注入/注入 解耦
// ActionContext context =ActionContext.getContext();
// Map<String, Object> req= context.getContextMap();
if(user.getName().equals("zhangsan")) {
req.setAttribute("name", user.getName());
// req.put("name", user.getName());
return "success";
}else {
return "error";
}
}
}
前台界面及效果图就不贴了,前台页面就是一个表单发送请求就行,其他所有实现代码已附上.
struts2与servlet的耦合
首先在使用耦合和解耦时得知道它的作用,前面也提到了,struts2是基于mvc设计模式的,特点就是高内聚、低耦合,之所以低耦合就是为了即使拆开某个模块,也不影响项目运行,也就是说每个模块的独立性,修改某个模块也不必要修改其他的模块功能。所以在使用struts2处理action层业务时,尽量使用
解耦
方式获取传递参数
耦合的两种方式:注入和非注入
注入方式:实现ServletRequestAware、ServletResponseAware
两个接口
public class HelloStruts implements ModelDriven<User>,ServletRequestAware,ServletResponseAware
实现之后会有两个方法:
private HttpServletRequest req;
private HttpServletResponse resp;
//注入式耦合
@Override
public void setServletResponse(HttpServletResponse response) {
this.resp=response;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.req=request;
}
非注入耦合:使用ServletActionContext
的方法获取request
、response
参数即可
//非注入耦合,和servlet关系紧密
ServletActionContext.getRequest();
ServletActionContext.getResponse();
struts2与servlet的解耦
解耦就是一种方式:
//非注入/注入 解耦
ActionContext context =ActionContext.getContext();
Map<String, Object> req= context.getContextMap();
//存值方式
req.put("name", name);
解耦方式实质上是获取到了请求参数的map集合,而servlet传值本质上也是一个map集合,所以解耦方式可以获取前台传递过来的参数集合,而获取request和response参数在struts2框架中也是为了获取前台参数,因为跳转路径啥的都不用转发或者重定向,直接配置文件搞定了…