Struts2

①Struts2是什么

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

优势:自动封装参数、参数校验、结果的处理(转发|重定向)、国际化、显示等待页面、防止表单重复提交。

struts2具有更加先进的架构以及思想

②搭建struts2框架

1)导包:struts-2.3.24\apps\blank\WEB-INF\lib  下的所有包 13个

2)书写Action类

public class HelloAction {
	public String hello(){
		System.out.println("hello world!");
		return "success";
	}
}

3)书写src/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>
	
	<!-- i18n:国际化. 解决post提交乱码 -->
	<constant name="struts.i18n.encoding" value="UTF-8"></constant>
	<!-- 指定反问action时的后缀名 
		http://localhost:8080/struts2_day01/hello/HelloAction.do
	-->
	<constant name="struts.action.extension" value="action"></constant>
	<!-- 指定struts2是否以开发模式运行
			1.热加载主配置.(不需要重启即可生效)
			2.提供更多错误信息输出,方便开发时的调试
	 -->
	<constant name="struts.devMode" value="true"></constant>
	
	

	<!-- package:将Action配置封装.就是可以在Package中配置很多action.
			name属性: 给包起个名字,起到标识作用.随便起.不能其他包名重复.
			namespace属性:给action的访问路径中定义一个命名空间
			extends属性: 继承一个 指定包
			abstract属性:包是否为抽象的; 标识性属性.标识该包不能独立运行.专门被继承
	  -->
	<package name="hello" namespace="/hello" extends="struts-default" >
		<!-- action元素:配置action类
				name属性: 决定了Action访问资源名.
				class属性: action的完整类名
				method属性: 指定调用Action中的哪个方法来处理请求
		 -->
		<action name="HelloAction" class="cn.pb.a_hello.HelloAction" method="hello" >
			<!-- result元素:结果配置 
					name属性: 标识结果处理的名称.与action方法的返回值对应.
					type属性: 指定调用哪一个result类来处理结果,默认使用转发.
					标签体:填写页面的相对路径
			-->
			<result name="success" type="dispatcher" >/hello.jsp</result>
		</action>
	</package>
	<!-- 引入其他struts配置文件 -->
	<include file="cn/pb/b_dynamic/struts.xml"></include>
	<include file="cn/pb/c_default/struts.xml"></include>
</struts>

4)将strtus2核心过滤器配置到web.xml中

  <!-- 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>

5)测试:http://localhost:8080/struts2Demo/hello/HelloAction

③struts2访问流程

④struts2常见配置

1)struts2默认常量配置位置:struts2-core-  .jar/org.apache.struts2/default.properties

2)修改struts2常量配置(方式先后也是加载顺序)

  •      方式1:src/struts.xml
  •      方式2:在src下创建struts.properties

  •       方式3:在项目的web.xml中
  <context-param>
  	<param-name>struts.i18n.encoding</param-name>
  	<param-value>UTF-8</param-value>
  </context-param>

加载顺序

default.properties
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml

3)动态方法调用

方式一

设置常量开启动态方法调用

<contant name="struts.enable.DynamicMethodInvocation" value="true"></contant>

  http://localhost:8080/strutsDemo/DemoAction!find.action

方式二

<action name="DemoAction_*" class="" method="{1}">

  http://localhost:8080/strutsDemo/DemoAction_find.action

4)struts2中的默认配置

5)创建action类的几种方式

      方式一:普通java类,struts2代码侵入性低

      方式二:实现Action接口,里面有execute方法,提供了action的方法规范,预制了一些字符串,作为返回结果使用

      方式三:继承ActionSupport,帮我们实现了一些接口,Validateable、ValidationAware、TextProvider、LocaleProvider..

⑤结果跳转方式

转发

		<action name="Demo1Action" class="cn.pb.a_result.Demo1Action" method="execute" >
			<result name="success" type="dispatcher" >/hello.jsp</result>
		</action>

重定向

		<action name="Demo2Action" class="cn.pb.a_result.Demo2Action" method="execute" >
			<result name="success" type="redirect" >/hello.jsp</result>
		</action>

转发到Action

		<action name="Demo3Action" class="cn.pb.a_result.Demo3Action" method="execute" >
			 <result name="success" type="chain">
			 		<!-- action的名字 -->
	             <param name="actionName">Demo1Action</param>
	             	<!-- action所在的命名空间 -->
	             <param name="namespace">/</param>
	         </result>
		</action>

重定向的Action

		<action name="Demo4Action" class="cn.pb.a_result.Demo4Action" method="execute" >
			<result  name="success"  type="redirectAction">
				 <!-- action的名字 -->
	             <param name="actionName">Demo1Action</param>
	             <!-- action所在的命名空间 -->
	             <param name="namespace">/</param>
            </result>
		</action>

⑥访问servletAPI的方式

原理:

方式一:通过ActionContext

方式二:通过ServletActionContext

方式三:通过实现接口的方式

⑦如何获得参数

补充:strutsMVC

补充:Action的生命周期

  • 每次请求到来时,都会创建一个新的Action实例
  • Action是线程安全的.可以使用成员变量接收参数

方式一:属性驱动获得参数(提供set方法)

方式二:对象驱动

方式三:模型驱动

集合类型页面显示的语法

private List<String> list;
<input type="text" name="list[2]"/>
 
private Map<String,String> map;
<input type="text" name="map['name']"/>

⑧OGNL表达式

OGNL:对象视图导航语言.  通过某种语法,存取Java对象的任意属性,调用Java对象的任意方法
OGNL要素:

表达式:核心,做什么。其实就是一个带有语义的字符串,这个字符串规定了操作的类型和操作的内容

根对象(Root):对谁进行操作,OGNL的操作对象,可以访问该对象和这个对象关联的对象。

Context对象:上下文环境,在哪里进行。Map类型的对象。需要使用#加上对象名称进行访问。

使用:

1)导包:struts2 的包中已经包含了.所以不需要导入额外的jar包

2)代码

 

语法:

基本取值

		User rootUser = new User("tom",18);
		//准备Context
		Map<String,User> context = new HashMap<String,User>();
		context.put("user1", new User("jack",18));
		context.put("user2", new User("rose",22));
		OgnlContext oc = new OgnlContext();
		oc.setRoot(rootUser);
		oc.setValues(context);
		//书写OGNL
		
		//取出context中键为user1对象的name属性
		String name = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
		String name2 = (String) Ognl.getValue("#user2.name", oc, oc.getRoot());

赋值

		User rootUser = new User("tom",18);
		//准备Context
		Map<String,User> context = new HashMap<String,User>();
		context.put("user1", new User("jack",18));
		context.put("user2", new User("rose",22));
		OgnlContext oc = new OgnlContext();
		oc.setRoot(rootUser);
		oc.setValues(context);
		//书写OGNL
		
		//将root中的user对象的name属性赋值
		Ognl.getValue("name='jerry'", oc, oc.getRoot());
		String name = (String) Ognl.getValue("name", oc, oc.getRoot());
		
		String name2 = (String) Ognl.getValue("#user1.name='rose',#user1.name", oc, oc.getRoot());

调用方法

		User rootUser = new User("tom",18);
		//准备Context
		Map<String,User> context = new HashMap<String,User>();
		context.put("user1", new User("jack",18));
		context.put("user2", new User("rose",22));
		OgnlContext oc = new OgnlContext();
		oc.setRoot(rootUser);
		oc.setValues(context);
		//书写OGNL
		
		//调用root中user对象的setName方法
		Ognl.getValue("setName('lilei')", oc, oc.getRoot());
		String name = (String) Ognl.getValue("getName()", oc, oc.getRoot());
		
		String name2 = (String) Ognl.getValue("#user1.setName('lucy'),#user1.getName()", oc, oc.getRoot());

调用静态方法

		User rootUser = new User("tom",18);
		//准备Context
		Map<String,User> context = new HashMap<String,User>();
		context.put("user1", new User("jack",18));
		context.put("user2", new User("rose",22));
		OgnlContext oc = new OgnlContext();
		oc.setRoot(rootUser);
		oc.setValues(context);
		//书写OGNL
		
		String name = (String) Ognl.getValue("@cn.itheima.a_ognl.HahaUtils@echo('hello 强勇!')", oc, oc.getRoot());
		//Double pi = (Double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
		Double pi = (Double) Ognl.getValue("@@PI", oc, oc.getRoot());

创建对象(List Map)

		User rootUser = new User("tom",18);
		//准备Context
		Map<String,User> context = new HashMap<String,User>();
		context.put("user1", new User("jack",18));
		context.put("user2", new User("rose",22));
		OgnlContext oc = new OgnlContext();
		oc.setRoot(rootUser);
		oc.setValues(context);
		//书写OGNL
		
		//创建list对象
		Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
		String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());
		String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());
	
		//创建Map对象
		Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
		String name3  = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
		Integer age  = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());

⑨OGNL与Struts2的结合

ValueStack中的两部分

    CompoundRoot root;

     transient Map<String,Object> context;

栈原理

根对象底层是通过ArrayList实现的栈,访问栈中属性的特点.由上到下。

public class CompoundRoot extends ArrayList{

查看值栈中两部分内容(使用DEBUG标签)

Root:自定义的那个Action.

Context:Context部分就是ActionContext数据中心

struts2与OGNL的结合体现

1)参数接收

如何获得值栈对象,值栈对象与ActionContext对象是互相引用的

2)配置文件中,语法:${ognl表达式}

3)struts标签

补充:request.getAttribute的查找顺序

⑩自定义拦截器

架构

创建拦截器

创建方式一:实现 Interceptor 接口,需要我们自己显式的重写init 、intercept、destory方法

创建方式二:继承 AbstractInterceptor,帮我们实现了init 、destory.我们只需要实现intercept方法

创建方式三:继承MethodFilterInterceptor.

注:拦截器中如果没有放行,而是return “success”,不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转

//功能: 定制拦截器拦截的方法.
//	定制哪些方法需要拦截.
//	定制哪些方法不需要拦截
public class MyInterceptor3 extends MethodFilterInterceptor{

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		//前处理
		System.out.println("MyInterceptor3 的前处理!");
		//放行
		String result = invocation.invoke();
		//后处理
		System.out.println("MyInterceptor3 的后处理!");
		
		return result;
	}

}

配置拦截器

步骤1:注册拦截器

步骤2:配置拦截器栈

步骤3:指定包中默认拦截器栈

	<package name="inter" namespace="/" extends="struts-default" >
	<interceptors>
	<!-- 1.注册拦截器 -->
		<interceptor name="myInter3" class="cn.pb.a_interceptor.MyInterceptor3"></interceptor>
	<!-- 2.注册拦截器栈 -->
		<interceptor-stack name="myStack">
			<!-- 自定义拦截器引入(建议放在20个拦截器之前) -->
			<interceptor-ref name="myInter3">
				<!-- 指定哪些方法不拦截
				 <param name="excludeMethods">add,delete</param> -->
				 <!-- 指定哪些方法需要拦截 -->
				 <param name="includeMethods">add,delete</param>
			</interceptor-ref>
			<!-- 引用默认的拦截器栈(20个) -->
			<interceptor-ref name="defaultStack"></interceptor-ref>
		</interceptor-stack>	
	</interceptors>
	<!-- 3.指定包中的默认拦截器栈 -->
	<default-interceptor-ref name="myStack"></default-interceptor-ref>
	<!-- 4.全局结果集 -->
    <global-results>
        <result name="toLogin" type="redirect">/login.jsp</result>
    </global-results>

了解:struts标签

标签体系

标签结构

1)控制标签

<!-- 遍历标签 iterator -->
<!-- ------------------------------------- -->
<s:iterator value="#list" ><s:property /><br>
</s:iterator>
<!-- ------------------------------------- --><hr>
<s:iterator value="#list" var="name" >
	<s:property value="#name" /><br>
</s:iterator>
<!-- ------------------------------------- --><hr>
<s:iterator begin="1" end="100" step="1"  >
	<s:property />|
</s:iterator>

<s:if test="#list.size()==4">
	list长度为4!
</s:if>
<s:elseif test="#list.size()==3">
	list长度为3!
</s:elseif>
<s:else>
	list不3不4!
</s:else>

2)数据标签

<s:property value="#list.size()" />
<s:property value="#session.user.name" />

3)表单标签

	<!-- struts2表单标签 -->
	<!-- 好处1: 内置了一套样式.  -->
	<!-- 好处2: 自动回显,根据栈中的属性  -->
	<!-- theme:指定表单的主题
			xhtml:默认
			simple:没有主题
	 -->
	<s:form action="Demo3Action" namespace="/" theme="xhtml" >
		<s:textfield name="name" label="用户名"  ></s:textfield>
		<s:password name="password" label="密码" ></s:password>
		<s:radio list="{'男','女'}" name="gender" label="性别" ></s:radio>
		<s:radio list="#{1:'男',0:'女'}" name="gender" label="性别" ></s:radio>
		<s:checkboxlist list="#{2:'抽烟',1:'喝酒',0:'烫头'}" name="habits" label="爱好" ></s:checkboxlist>
		<s:select list="#{2:'大专',1:'本科',0:'硕士'}" headerKey="" headerValue="---请选择---" name="edu" label="学历" >
		</s:select>
		<s:file name="photo" label="近照" ></s:file>
		<s:textarea name="desc" label="个人简介" ></s:textarea>
		<s:submit value="提交" ></s:submit>
	</s:form>

4)非表单标签

this.addActionError("i am wrong!");
<s:actionerror/>    取出信息

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值