struts2框架学习笔记

第一天 Struts2概述、入门、常见配置,Action编写

一、struts2的概述

Struts2 是一个基于MVC设计模式的web层的框架。Struts2相对于Struts1内核已经发生了很大的变化。常见的web层的框架有:struts2、struts1、bebwork、springMVC

二、Struts2的入门小案例

2.1解压Struts2的开发包会得到:

①apps:Struts2提供的应用,war文件:web项目打包成war包,可以直接放到tomcat
②docs:Struts2 的开发文档和API
③lib:Struts2开发的jar包
④src:Struts2的源码

2.2创建项目,引入jar包

在apps中找到struts2-blank.war解压得到里面的jar包
在这里插入图片描述

2.3创建一个JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Struts2的入门</h1>
<h3><a href="${pageContext.request.contextPath }/hello.action">Struts2的入门</a></h3>
</body>
</html>

2.4编写Action类

package com.itheima.struts.demo1;
/**
 * Struts2的入门案例类
 * @author Administrator
 *
 */
public class HelloAction {

	/**
	 * 提供一个方法
	 * 方法名是固定的,公有的,返回值是String类型,方法名是execute,在这个方法中不能传递参数
	 */
	public String execute(){
		System.out.println("HelloAction执行了。。。。。 ");
		return null;
	}
}

2.5对Action进行配置

<?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>
 	<!-- Struts2为了Action配置,通过包进行管理 -->
    <!-- 配置Struts的包 -->
	<package name="demo1" extends="struts-default" namespace="/">
		<!-- 配置Action -->
		<action name="hello" class="com.itheima.struts.demo1.HelloAction"></action>
	</package>
</struts>

2.6配置前端控制器(核心过滤器)

  <!-- 配置Struts2的核心过滤器 -->
  <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>

2.7修改Action中的返回值

package com.itheima.struts.demo1;
/**
 * Struts2的入门案例类
 * @author Administrator
 *
 */
public class HelloAction {

	/**
	 * 提供一个方法
	 * 方法名是固定的,公有的,返回值是String类型,方法名是execute,在这个方法中不能传递参数
	 */
	public String execute(){
		System.out.println("HelloAction执行了。。。。。 ");
		return “success”;
	}
}

2.8配置Struts.xml里面的页面跳转

在这里插入图片描述

2.9编写success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>跳转成功页面!!!!!</h1>
</body>
</html>

三、Action的配置

3.1packa相关的配置

①package标签称为包,这个包与Java包的概念不一样,这个包是为了更好的管理action的配置
②【package标签的属性】

name包的名称,只有在一个项目中不重名即可
extends继承哪个包,通常值为struts-default
namespace名称空间,与action标签中的name属性共同决定访问路径:名称空间有三种写法:1带名称的名称空间:namespace="/aaa";根名称空间:namespace="/";默认名称空间:namespace=""
abstract抽象的,用于其他包的继承

3.2action相关的配置

①action标签配置action类
②【action标签的属性】

name与namespace属性共同决定访问路径
classAction类的全路径
method执行action中的哪个方法的方法名,默认值是execute
converter用于设置类型转换器

3.3常量的配置

在Struts2中提供了很多的常量(在default.properties)
在Struts2中有三个地方可以修改常量的值:
①struts.xml中进行修改
在这里插入图片描述
②在struts.properties中修改

struts.action.extension=action

③web.xml中配置

<init-param>
	<param-name>struts.action.extendsion</param-name>
	<param-value>xyz</param-value>
</init-param>

3.4分模块开发的配置

在这里插入图片描述

四、Action类的写法

4.1Action类是POJO类

public class HelloAction {

	/**
	 * 提供一个方法
	 * 方法名是固定的,公有的,返回值是String类型,方法名是execute,在这个方法中不能传递参数
	 */
	public String execute(){
		System.out.println("HelloAction执行了。。。。。 ");
		return "success";
	}
}

4.2Action实现了一个Action的接口

实现接口的方式提供了五个常量(五个逻辑视图的名称)
SUCCESS 成功
ERROR 失败
LOGIN 登录出错页面跳转
INPUT 表单校验的时候出错
NONE 不跳转

public class ActionDemo2 implements Action{

	@Override
	public String execute() throws Exception {
		System.out.println("ActionDemo2执行了");
		return NONE;
	}

4.3继承ActionSupport类

public class ActionDemo3 extends ActionSupport{
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("ActionDemo3执行了");
		return NONE;
	}
}

推荐使用第三种:继承ActionSupport类,这个类提供了数据校验与国际化等操作方法

五、Action的访问

一般就是使用通配符的方式:

<action name="product_*" class="com.itheima.struts.demo3.ProductAction" method="{1}"></action>

第二天

一、servlet的API的访问

在使用Struts2的框架的过程中,发现Struts2 和Servlet的API是解耦合的。在实际开发中,经常使用到servlet的API,比如进行登录,将用户的信息保存到Session中,有的时候需要向页面输出一些内容,用到response对象。涉及到servlet的API的访问。

1.1完全解耦合的方式

public class RequestDemo1 extends ActionSupport{
	@Override
	public String execute() throws Exception {
		//1 接受参数
		//利用struts里面的对象ActionContext
		ActionContext context = ActionContext.getContext();
		//调用ActionContext中的方法
		Map<String, Object> map = context.getParameters();
		for (String  key : map.keySet()) {
			 String [] value = (String[])map.get(key);
			 System.out.println(key + "...." + Arrays.toString(value));
		}
		//2向域对象中存入数据
		context.put("reqName", "reqValue");
		context.getSession().put("sessName", "sessValue");
		context.getApplication().put("appName", "appValue");
		return "success";
	}
}

注意:这种方式只能获得代表request、session、application的数据的map集合,不能操作这些对象本身的方法。

1.2使用servlet的API原生方式

public class RequestDemo2 extends ActionSupport {

	@Override
	public String execute() throws Exception {
		//一、接受数据
		//直接获得request对象,通过ServletActionContext
		HttpServletRequest request = ServletActionContext.getRequest();
		Map<String, String[]> map = request.getParameterMap();
		for (String key : map.keySet()) {
			String[] values = map.get(key);
			System.out.println(key + "=====" + Arrays.toString(values));
		}
		//二、向域对象中保存数据
		//向request中保存数据
		request.setAttribute("reqName", "小豹子是笨蛋");
		//向session中保存数据
		request.getSession().setAttribute("sessName", "小煤球是傻瓜");
		//向application中保存数据
		ServletActionContext.getServletContext().setAttribute("appName", "小茗子是蛋瓜");
		return SUCCESS;
	}
}

注意:这种方式可以操作域对象的数据,同时也可以获取到对象的方法
此外还有接口注入的方式。

二、结果页面的配置

2.1全局结果页面的配置

全局结果页面:在包中只需要配置一次,其他在这个包中的所有action只要返回了这个值,都可以跳转到这个页面。
在这里插入图片描述

2.2局部结果页面的配置

局部结果页面:只能在当前的action中的配置有效。
在这里插入图片描述

2.3result标签的配置

result标签用于配置页面的跳转,在result标签上有两个属性。
name:逻辑视图的名称,默认值SUCCESS
type:页面跳转的类型:`

dispatcher默认值,请求转发(action转发JSP)
redirect重定向(action重定向JSP)
chain转发(action转发action)
redirectAction重定向(action重定向action)
streamStruts2提供下载功能

三、 数据封装

3.1属性驱动:提供属性set方法的方式(不常用)

/**
 * 数据封装的方式一:提供属性set方法的方式
 * @author Administrator
 *
 */
public class UserAction1 extends ActionSupport {
	//提供对应的属性
	private String username;
	private String password;
	private Integer age;
	private Date birthday;
	private Double salary;
	public void setUsername(String username) {
		this.username = username;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	@Override
	public String execute() throws Exception {
		// 接收数据
		System.out.println(username);
		System.out.println(password);
		System.out.println(age);
		System.out.println(birthday);
		System.out.println(salary);
		//封装数据
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setAge(age);
		user.setBirthday(birthday);
		user.setSalary(salary);
		
		return NONE;
	}
}

3.2属性驱动:页面提供表达式

public class UserAction2 extends ActionSupport {
	//提供一个user对象
	private User user;
	//提供set与get方法
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	@Override
	public String execute() throws Exception {
		System.out.println(user);
		return NONE;
	}
}

3.3模型驱动的方式(最常用的方式)

public class UserAction3 extends ActionSupport implements ModelDriven<User>{
	private User user = new User();

	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		return NONE;
	}

	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		System.out.println(user);
		return user;
	}
}

模型驱动方式只能同时向一个对象中封装数据。
使用第二种可以同时向多个对象中封装数据

3.4封装数据到list集合中

在这里插入图片描述

public class ProductAction1 extends ActionSupport {
	private List<Product> products;
	
	
	public List<Product> getProducts() {
		return products;
	}

	public void setProducts(List<Product> products) {
		this.products = products;
	}

	@Override
	public String execute() throws Exception {
		for (Product product : products) {
			System.out.println(product);
		}
		return NONE;
	}
}

3.5封装数据到map集合中

在这里插入图片描述

public class ProductAction2 extends ActionSupport {
	
	private Map<String,Product> map ;
	
	public Map<String, Product> getMap() {
		return map;
	}

	public void setMap(Map<String, Product> map) {
		this.map = map;
	}

	@Override
	public String execute() throws Exception {
		for (String key : map.keySet()) {
			Product product = map.get(key);
			System.out.println(key + "   " + product);
		}
		return NONE;
	}
}

第三天

一、OGNL

OGNL:对象导航语言,比EL表达式强大很多倍的语言。
EL:从域对象中获取数据,从EL的11个对象中获取${name} ${pageContext.request.contextPath}
OGNl:调用对象的方法。获取Struts2值栈的数据,OGNL其实是第三方的表达式语言

1.1调用对象的方法


    	public void demo1() throws OgnlException{
		OgnlContext context = new OgnlContext();
		Object root = context.getRoot();
		Object obj = Ognl.getValue("'hello'.length()", context, root);
		System.out.println(obj);
	}

1.2调用对象的静态方法

	public void demo2() throws OgnlException{
		OgnlContext context = new OgnlContext();
		Object root = context.getRoot();
		Object obj = Ognl.getValue("@java.lang.Math@random()", context, root);
		System.out.println(obj);
	}

执行表达式:@类名@方法名

1.3获取root中的数据(不需要加#)

	public void demo3() throws OgnlException{
		OgnlContext context = new OgnlContext();
		context.setRoot(new User("aaa","123"));
		Object root = context.getRoot();
		Object username = Ognl.getValue("username", context, root);
		Object password = Ognl.getValue("password", context, root);
		System.out.println(username + "  " + password);
	}

1.4获取context中的数据(需要加#)

	public void demo4() throws OgnlException{
		OgnlContext context = new OgnlContext();
		Object root = context.getRoot();
		context.put("name", "小豹子");
		Object name = Ognl.getValue("#name", context, root);
		System.out.println(name);
	}

二、值栈

2.1什么是值栈

值栈:valuestack:类似于一个数据中转站(Struts2中的数据都保存在值栈中)
valuestack接口,实现类OgnlValueStack对象
ValueStack贯穿整个action的生命周期,(action一旦创建了,框架就会创建一个valueStack对象)

2.2值栈的内部结构

值栈有两个主要的区域:
root区域:其实就是一个ArrayList。里面一般放对象。过去root数据不需要加#。
context区域:其实就是一个map。里面放的是web开发的常用的对象数据的引用。获取context数据需要加#。
我们所说的操作值栈通常是操作root区域。

2.3值栈与actioncontext的关系

servletContext servlet的上下文
actionContext action的上下文
①通过源码,当请求过来的时候,执行过滤器的doFilter方法,在这个方法中创建actioncontext,在创建actioncontext过程中,创建valuestack对象,将valuestack对象传递给actioncontext对象,所以可以通过actioncontext对象获取值栈对象。
②actioncontext对象之所以可以访问servlet的API(访问域对象的数据),因为在其内部有值栈的引用。

2.4值栈的获取

ValueStack valueStack = ActionContext.getContext().getValueStack();
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

一个action实例只有一个值栈对象

2.5操作值栈——向值栈中存入数据

①在action中提供属性的get方法的方式
②使用valuestack的本身的方法push

public class ValueStackDemo5 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		User user = new User("赵洪","1323");
		ActionContext.getContext().getValueStack().push(user);
		List<User> list = new ArrayList<User>();
		list.add(new User("aaa","111"));
		list.add(new User("bbb","222"));
		list.add(new User("ccc","333"));
		ActionContext.getContext().getValueStack().set("list", list);
		
		ServletActionContext.getRequest().setAttribute("name", "李兵R");
		ServletActionContext.getRequest().getSession().setAttribute("name", "s赵洪");
		ServletActionContext.getServletContext().setAttribute("name", "a邓志龙");
		return super.execute();
	}
}
<h1>查看值栈的内部结构</h1>
<s:debug></s:debug>
<s:property value="username"/>
<s:property value="password"/>
<br>
<!-- 获取集合种的数据 -->
<s:property value="list[0].username"/>
<s:property value="list[0].password"/>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/>
<s:property value="list[2].username"/>
<s:property value="list[2].password"/>
<!-- 获取context中的数据 -->
<s:property value="#request.name"/>
<s:property value="#session.name"/>
<s:property value="#application.name"/>
<s:property value="#attr.name"/>
<s:property value="#request.name"/>

第四天

一、拦截器

1.1什么是拦截器

拦截器:interceptor,起到拦截action的作用。
filter:过滤器,过滤从客户端向服务器发送的请求
拦截器:拦截客户端对action的访问。更细致的拦截。拦截action中具体的方法
Struts2核心的功能都是依赖拦截器来实现

1.2Struts2的执行流程

客户端向服务器发送一个action请求,执行核心过滤器(dofilter)方法。在这个方法中,调用executeAction()方法,在这个方法内部调用dispatcher.serviceAction();在这个方法内部创建一个action代理,最终执行的是action代理中的execute(),在代理中执行execute方法中调用Actioninvocation的invoke方法。这个方法内部递归执行一组拦截器(完成部分功能),如果没有下一个拦截器,就会执行目标action,根据acting返回的结果进行页面跳转。

二、 拦截器入门

2.1编写拦截器类

public class InterceptorDemo1 extends AbstractInterceptor{

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("InterceptorDemo1执行了。。。。。");
		String obj = invocation.invoke();
		System.out.println("InterceptorDemo1执行完毕了。。。");
		return obj;
	}

}

2.2配置拦截器

<struts>
	<constant name="struts.action.extension" value="action"/>
	<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
	<package name="demo1" extends="struts-default" namespace="/">
		<interceptors>
			<interceptor name="interceptorDemo1" class="com.itheima.web.interceptor.InterceptorDemo1"></interceptor>
			<interceptor name="interceptorDemo2" class="com.itheima.web.interceptor.InterceptorDemo2"></interceptor>
			<interceptor-stack name="myStack">
				<interceptor-ref name="defaultStack"/>
				<interceptor-ref name="interceptorDemo1"/>
			    <interceptor-ref name="interceptorDemo2"/>
			</interceptor-stack>
		</interceptors>
		
		<action name="actionDemo1" class="com.itheima.web.action.ActionDemo1">
			<result>/demo1/demo1.jsp</result>
			<interceptor-ref name="myStack"/>
		</action>
	</package>
</struts>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值