Struts入门
Struts2简介
1、Struts2是Apache组织下一个基于MVC设计模式的Web应用框架。
2、Struts2是Struts的下一代产品,是Struts1 + WebWork合并的全新框架。
3、Struts2采用拦截器Filter为核心机制,就一个开源的轻量级的,应用于表示层(Web层、View)的框架。
mavne依赖
1、新建maven项目,在你的pom.xml中配置 struts2框架核心依
<!-- 引用struts2框架核心依赖 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.16</version>
</dependency>
web.xml中配置核心拦截器
在项目webapp/MEB-INF/web.xml文件中配置Struts2核心拦截器:StrutsPrePareAndExectueFilter。
当用户请求匹配的URL时,执行核心栏截器。
扩展知识:由于Web应用是基于请求/响应架构的应用,所以不管哪个MVC Web框架,都需要在web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架介入Web应用中。
下面配置中当请求以.action结尾的请求时就会跳转到核心拦截器中进行处理(这也就是自定义MVC中的中央处理器)
web.xml
<!--定义struts2的核心Filter-->
<filter>
<filter-name>struts2</filter-name>
<!--Struts2.1.3版本起使用的核心过滤器-->
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!--让Struts2的核心Filter拦截所有请求-->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<!--url-pattern>*.action</url-pattern-->
</filter-mapping>
注意事项:
Struts 2.1版本之前用的核心过滤器是FilterDispacther
Struts 2.1~2.4版本用的是StrutsPrepareAndExecuteFilter
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
Struts 2.5版本用的也是StrutsPrepareAndExecuteFilter,但路径有所改变:
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
定义Action
Action是业务控制器,是Struts2的重要组成部分之一。
Action是MVC中的C,也就是控制器。
该类负责调用Model里的方法来处理请求。我们的中央处理器会根据这个请求的路径去调用相对于的Action类的相对于的请求处理方法。下面我们定义一个DomeActioin(后续添加代码)
public class ActionDome{
}
配置文件编写
说明:其实定义一个xml配置文件就ok,但是为了项目的模块划分就分成3个配置文件。方便管理。
struts.xml
这是核心配置文件,struts读取的就是这个xml文件。我们通过include指令引入另外其他自定义的文件
<?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-default.xml"></include>
<include file="struts-base.xml"></include>
<include file="struts-sy.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.i18n.encoding" value="UTF-8" />
<!-- 开启动态方法调用 -->
<constant name="struts.devMode" value="true" />
<!-- 不重启的情况下能修改代码理解生效 -->
<constant name="struts.configuration.xml.reload" value="true" />
<!-- 和上面一样 -->
<constant name="struts.i18n.reload" value="true" />
<!-- 开启动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!-- 实用动态方法调用必须配置的 -->
<package name="base" extends="struts-default" abstract="true">
<!--
在statu2.5版本之后,加了 regex:.* 默认将动态方法调用关闭,abstract 也要为true才能动态方法调用
这是处于系统安全考虑的。
-->
<global-allowed-methods>regex:.*</global-allowed-methods>
</package>
</struts>
struts-sy.xml
请求相关处理的xml配置,struts引入了包的概念
<?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="sy" extends="base" namespace="/sy"><!--这时引入了包的概念-->
<!----->
<action name="/dome_*" class="com.cpc.web.ActionDome" method="{1}">
<result name="rs">/rs.jsp</result><!--指定状态返回路径-->
</action>
</package>
</struts>
动态方法调用
Aciton代码
public class ActionDome {
/**
* 动态方法调用add
* @return
*/
public String add() {
System.out.println("my is add");
return "rs";
}
/**
* 动态方法调用del
* @return
*/
public String del() {
System.out.println("my is del");
return "rs";
}
}
JSP页面代码
<!--调用ActionDome的add方法并且跳转到rs.jsp页面-->
<a href="${pageContext.request.contextPath}/sy/dome_add.action">新增</a>
<!--调用ActionDome的del方法并且跳转到rs.jsp页面-->
<a href="${pageContext.request.contextPath}/sy/dome_del.action">删除</a>
前台传递数据到后台
1、实现ModelDriven
Action代码
public class ActionDome implements ModelDriven<Cal>{
private Cal cal1 = new Cal();
/**
* 通过实现ModelDriven接口来做到前后台传值
* @return
*/
@Override
public Cal getModel() {
// TODO Auto-generated method stub
return cal1;
}
/**
* 实现 ModelDriven 获取前台参数
* @return
*/
public String accept1() {
System.out.println("accept1:" + cal1);
//跳转到rs.jsp
return "rs";
}
}
jsp页面
<a href="${pageContext.request.contextPath}/sy/dome_accept1.action?num1=20&&num2=5">accept1</a>
2、通过实例名.属性名 获取前台参数
Action代码
public class ActionDome{
private Cal cal2;
//这是公开 cal2和sex的get/set方法,如果不公开那么参数将无法传递
public Cal getCal2() {
return cal2;
}
public void setCal2(Cal cal2) {
this.cal2 = cal2;
}
/**
* 通过 实例名.属性名 获取前台参数
* @return
*/
public String accept2() {
System.out.println("accept2:" + cal2);
return "rs";
}
}
JSP页面
<a href="${pageContext.request.contextPath}/sy/dome_accept2.action?cal2.num1=20&&cal2.num2=5">accept2</a>
3通过get/set方法
Aciton代码
public class ActionDome{
private String sex;
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
/**
* 通过 get/set 获取前台参数
* @return
*/
public String accept3() {
System.out.println("accept3:" + sex);
return "rs";
}
}
jsp页面
<a href="${pageContext.request.contextPath}/sy/dome_accept3.action?sex=nv">accept3</a>
上面的第二中和第三种可用之间在跳转后的rs.jsp通过el表达式获取如${sex}
但通过实现ModelDriven接口却不会将数据自动的转到rs.jsp,这是就需要我们获取request/respons进行数据传递了
J2EE容器交互
注入(耦合和解耦)
因为解耦太麻烦没没人用不讲,下面看看耦合方式。其实也就是实现ServletRequestAware,或ServletResponseAware接口
public class ActionDome implements ServletRequestAware{
private HttpServletRequest req;
@Override
public void setServletRequest(HttpServletRequest req) {
// TODO Auto-generated method stub
this.req = req;
}
}
非注入(耦合和解耦)
推荐使用,贼简单
public String accept1() {
System.out.println("accept1:" + cal1);
//之间获取请求对象
HttpServletRequest req = ServletActionContext.getRequest();
req.setAttribute("cal1", cal1);
return "rs";
}