struts2 框架
1.简介
Struts2框架是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构。它利用并延伸了Java Servlet API,鼓励开发者采用MVC架构。Struts2以WebWork优秀的设计思想为核心,吸收了Struts框架的部分优点,提供了一个更加整洁的MVC设计模式实现的Web应用程序框架。
1.基于MVC框架
2.WEB层基于前端控制器模式 ---->配置过滤器
2.入门案例
步骤1:创建一个maven的项目,导入坐标 (或者导入相对应的jar包)
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.24</version>
</dependency>
</dependencies>
步骤2:在java包下编写一个类
package com.action.demo1;
public class Login
{
public String sayHello()
{
System.out.print("hello World");
return "ok";
}
}
步骤3:准备jsp页面及回执页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<h3>快速入门</h3>
<a href="${pageContext.request.contextPath}/hello.action">快速入门按钮</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<h3>跳转成功页面</h3>
<%--<a href="${pageContext.request.contextPath}/hello.action">跳转成功页面</a>--%>
</body>
</html>
步骤4:创建webapp目录及其子目录WEB-INF,编写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" 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>Struts Blank</display-name>
<!--配置 过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- 常量的编写 这个是最后加载 会覆盖struts.xml文件中配置-->
<!--<init-param>
<param-name>struts.action.extension</param-name>
<param-value>action,,</param-value>
</init-param>-->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
步骤5:在resources包下创建一个名为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>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<!--name: 超链接地址 class:包名 method:方法名 此处利用了反射原理-->
<action name="hello" class="com.action.login" method="sayHello">
<!--准备回执页面-->
<result name="ok" >success.jsp</result>
</action>
</package>
<include file="example.xml"/>
<!-- Add packages here -->
</struts>
3.struts2的执行流程
1.当浏览器访问action的时候,会被前端控制器拦截住执行dofilter方法;
2.在dofilter方法中会判断访问是否是action.如果不是,放行;如果是,会往struts2核心程序里面走
3.在核心程序中,会创建action的代理对象,但是这个代理对象并不是真正干活的对象因为在它里面又调用了一个别的对象的方法(invocation.invoke())--> 反射
4. 执行完毕所有的默认拦截器 会执行自己的action方法,action执行完毕会返回一个逻辑视图名给配置文件
5.配置文件接收到指定的逻辑视图名会走指定的页面
反射原理的代码 Clazz z = Class.forName("com.action.login");
Method m = z.getMethod("sayHello");
String result = (String)m.invoke(action);
---> result ="ok";
自己理解的执行流程
用户访问浏览器,客户端发送一个Http请求
请求被web.xml解析,如果配置struts的过滤器中url-pattern中路径满足,则请求被struts核心过滤器StrutsPreparedAndExecuteFilter匹配到,调用init()方法并加载一些配置文件
然后解析struts.xml文件中的action,寻找与返回地址相匹配的name属性的名字
如果找到相匹配的名字则通过 class和name两个属性,通过反射机制,返回一个逻辑视图给配置文件
通过配置文件接受到逻辑视图相对应的指定页面
响应客户端
4.加载顺序(*)
核心过滤器在创建后,调用init方法,会加载一些配置文件
1.加载 default.propeties 加载常量
2.加载struts-default.xml struts-plugin.xml 等 加载核心功能 加载重点配置 加载配置前端核心控制器
3.加载自定义的struts.properties
4.加载用户自定义配置提供者
5.加载web.xml
后加载的配置文件会覆盖之前加载的配置文件
5.配置标签(*)
1.package 属性: name:包名(不能相同) namepace:"/" (根名称空间) “/aaa”(从根目录开始下的aaa包) extends:“sturtus-default” (一般为固定值)
2.action 属性: name:.action 前缀 class:类名 method:方法名
3.result (可出现多个标签) name:访问名称 type:类型(重定向/转发)
6.常量的编写(*)
一般在3个位置修改: 1. struts.xml(一般在这个文件中修改) 2. struts.properties 3. web.xml
<!--编写常量 后缀名-->
<constant name="struts.action.extension" value="do,,"/>
<!--编写上传值 (约2mb)-->
< constant name="struts.multipart.maxSize" value="2097152"/>
<!--上传路径,不写默认为本地路径-->
< constant name="struts.multipart.saveDir"/>
<!--缓存 生产环境下要关掉 一般不需要管-->
<constant name ="struts.serve.static.browserCache" value="false"></constant>
7.分包的配置
<!--方式一 引入其他的配置文件-->
<include file=""com/xxx/xxx/struts_user.xml/>
8.三种配置方式(*)
1.普通类
package com.action;
public class Demo_action
{
public String execute()
{
System.out.println("Demo_action 是一个pojo类");
return null;
}
}
2.实现Action接口
package com.action;
import com.opensymphony.xwork2.Action;
public class Demo_action2 implements Action
{
public String execute() throws Exception
{
System.out.println("Demo_action2实现了Action接口");
// return NONE; //表示页面不跳转
return SUCCESS;
}
}
3.继承ActionSupport类
package com.action;
import com.opensymphony.xwork2.ActionSupport;
public class Demo_action3 extends ActionSupport
{
@Override
public String execute() throws Exception
{
System.out.println("demo_action 继承了ActionSupport 第三种继承方法");
return NONE;
}
}
配置文件
<package name="default" namespace="/" extends="struts-default">
<!--name: 超链接地址 class:包名 method:方法名-->
<action name="hello" class="com.action.Login" method="sayHello">
<result name="ok" >success.jsp</result>
</action>
<!--第一种配置方式-->
<action name="demo_action" class="com.action.Demo_action"/>
<!--第二种配置方式-->
<action name="demo_action2" class="com.action.Demo_action2" >
<result name="success">success.jsp</result>
</action>
<!--第三种配置方式-->
<action name="demo_action3" class="com.action.Demo_action3" />
</package>
9.访问方式(*)
1.传统方式
package com.action.demo2;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport
{
// 保存用户
public String save()
{
System.out.println("保存用户");
return NONE;
}
// 删除用户
public String delete()
{
System.out.println("删除用户");
return NONE;
}
}
2.通配符方式
package com.action.demo2;
import com.opensymphony.xwork2.ActionSupport;
public class LinkManAction extends ActionSupport
{
// 保存用户
public String save()
{
System.out.println("通配符添加用户");
return "saveOk";
}
// 删除用户
public String delete()
{
System.out.println("通配符删除用户");
return "deleteOk";
}
}
配置文件
<package name="demo2" namespace="/" extends="struts-default">
<!--传统访问方式-->
<action name="saveUser" class="com.action.demo2.UserAction" method="save"/>
<action name="deleteUser" class="com.action.demo2.UserAction" method="delete"/>
<!--通配符访问方式-->
<action name="LinkMan_*" class="com.action.demo2.LinkManAction" method="{1}">
<result name="saveOk">/demo1/success.jsp</result>
<result name="deleteOk">/demo1/success.jsp</result>
</action>
</package>
jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>demo2</title>
</head>
<body>
<h3>传统的配置文件的方式</h3>
<a href="${pageContext.request.contextPath}/saveUser.action">添加用户</a>
<a href="${pageContext.request.contextPath}/deleteUser.action">删除用户</a>
<h3>通配符的配置文件的方式</h3>
<a href="${pageContext.request.contextPath}/LinkMan_save.action">通配符添加用户</a>
<a href="${pageContext.request.contextPath}/LinkMan_delete.action">通配符删除用户</a>
</body>
</html>
3.动态方法访问
注意:动态方法访问必须开启,struts默认为false
java代码
package com.action.demo2;
import com.opensymphony.xwork2.ActionSupport;
public class DynamicAction extends ActionSupport
{
// 保存用户
public String save()
{
System.out.println("动态方法访问添加用户");
return NONE;
}
// 删除用户
public String delete()
{
System.out.println("动态方法访问删除用户");
return NONE;
}
}
配置文件
<!--开启动态方法访问-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="demo2" namespace="/" extends="struts-default">
<!--动态访问-->
<action name="Dynamic" class="com.action.demo2.DynamicAction"/>
</package>