手把手撸码struts2--day2

第一张 结果视图的配置

1.1result标签===========================

在sturts.xml文件中,Result的配置非常简单,使用元素来配置Result逻辑视图与物理视图之间的映射,元素可以有name和type属性,但这两种属性都不是必选的。

作用:
		为动作指定结果视图。
属性:
	name:逻辑视图的名称,对应着动作方法的返回值。默认值是success。 
	type:结果类型,指的就是用什么方式转到定义的页面。默认是dispatcher。
		type的常用取值:
			dispatcher:(默认值)
				使用请求转发,转向一个页面。
			redirect:
				使用重定向,转向一个页面。它可以用于重定向到另外一个动作。
			redirectAction:
				使用重定向,前往指定的动作。
用法:
	<result name="success" type="redirect">hello2.action</result>
	<result name="success" type="dispatcher">/success.jsp</result>

1.2配置全局结果视图

1.2.1局部结果视图和全局结果视图:

配置在action标签内的result,我们成为局部结果视图,它只能由当前action使用。
而在实际开发中,有很多页面,每个action可能都会用到。
比如:success.jsp,error.jsp,login.jsp等等。
当我们很多action都用到了login.jsp,在每个action标签中都配置一次,显然是不合理的,这个时候我们就用到了全局结果视图。

1.2.2配置方式:

	<package name="myDefault" extends="struts-default" abstract="true">
		<global-results>
			<result name="login">/login.jsp</result>
		</global-results>
	</package>	

1.3局部结果视图和全局结果视图的优先级

action在执行时,先找局部结果视图,没找到再找全局的。

1.4struts2提供的结果类型

在Struts2中,当框架调用Action对请求进行处理后,就要向用户呈现一个结果视图。在Struts2中,预定义了多种ResultType,其实就是定义了多种展示结果的技术。
一个结果类型就是实现了com.opensymphony.xwork2.Result接口的类,Struts2把内置的都放在struts-default包中,sturts-default包就是配置包的父包,这个包定义在struts2-core-2.3.24.jar包中的根目录下的struts-default.xml文件中,可以找到相关的的定义。
每个元素都是一种视图技术或者跳转方式的封装,其中的name属性指出在元素中如何引用这种视图技术或者跳转方式,对应着元素的type属性。Struts2中预定义的ResultType如表所示。

Struts2中预定义的ResultType
属性说明
chain用来处理Action链,被跳转的Action中仍能获取上个页面的值,如request信息。
dispatcher用来转向页面,通常处理JSP,是默认的结果类型。
freemarker用来整合FreeMarker模板结果类型。
httpheader用来处理特殊的HTTP行为结果类型。
redirect重定向到一个URL,被跳转的页面中丢失传递的信息。
redirectAction重定向到一个Action,跳转的页面中丢失传递的信息。
stream向浏览器发送InputStream对象,通常用来处理文件下载,还可用于Ajax数据。
velocity用来整合Velocity模板结果类型。
xslt用来整合XML/XSLT结果类型。
plainText显示原始文件内容,例如文件源代码。
postback使得当前请求参数以表单形式提交

其中字体加粗的几个值比较常用,需要重点记忆。其他的了解即可。

第三章 第3章访问Servlet的API的两种方式===================

3.1使用ServletActionContext类的方式

为了直接访问Servlet API,Struts2框架提供了ServletActionContext类,在实际开发中,这也是我们采用最多的方式。该类包含了几个常用的静态方法,具体如下:
在这里插入图片描述

  • static HttpServletRequest getRequest():获取Web应用的HttpServletRequest对象。

  • static HttpServletResponse getResponse():获取Web应用的HttpServletResponse对象。

  • static ServletContext getServletContext():获取Web应用的ServletContext对象。

  • static PageContext getPageContext():获取Web应用的PageContext对象。
    接下来,讲解如何通过ServletActionContext访问Servlet API。使用方式如下:

/**
 * 在struts2框架中有三种方式可以获取到ServletAPI对象
 * ServletAPI对象包含了:
 * 		request,response,HttpSession,ServletContext
 * 第一种方式:
 * 	使用的是ServletActionContext对象,它里面提供了一些静态方法,可以让我们获取到ServletAPI
 * 此种方式,使我们实际开发中采用最多的方式
 * 此时我们还要记住一件事:
 * 	这四个对象,有一个已经变了,和其他三个不一样,找出来,记住。
 * 
 * 	org.apache.struts2.dispatcher.StrutsRequestWrapper@1577071		它是那个不一样的
	org.apache.catalina.connector.ResponseFacade@1973ca4
	org.apache.catalina.session.StandardSessionFacade@e4d72
	org.apache.catalina.core.ApplicationContextFacade@fe7e93
 * 
 */
public class HelloAction extends ActionSupport{

	private HttpServletRequest request;
	private HttpServletResponse response;
	private HttpSession session;
	private ServletContext application;
	/**
	 * @return
	 */
	public String sayHello(){
		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		session = request.getSession();
		application = ServletActionContext.getServletContext();
		
		System.out.println(request);
		System.out.println(response);
		System.out.println(session);
		System.out.println(application);
		return SUCCESS;
	}
}

3.2通过实现action接口的方式

Struts2还提供了一系列接口,具体如下:

  • ServletRequestAware:实现该接口的Action可以直接访问Web应用的HttpServletRequest实例。
  • ServletResponseAware:实现该接口的Action可以直接访问Web应用的HttpServletResponse实例。
  • SessionAware:实现该接口的Action可以直接访问Web应用的HttpSession实例。
  • ServletContextAware:实现该接口的Action可以直接访问Web应用的ServletContext实例。
/**
 * 在struts2框架中有三种方式可以获取到ServletAPI对象
 * ServletAPI对象包含了:
 * 		request,response,HttpSession,ServletContext
 * 第三种方式:
 * 	采用实现接口的方式,来获取对象
 * 能够使用对象的原因:
 * 	是因为在我们的sayHello方法执行之前,已经有一些拦截器执行了。
 *  通过struts-default.xml我们能知道默认的拦截器栈defaultStack,
 *  在我们的动作配置时,默认就会有该拦截器栈中的所有拦截器执行。先正序,再倒序。
 *  
 *  帮我们给对象赋值全靠一个名称为servletConfig的拦截器
 *  
 *  拦截器的重要性:
 *  	他可以在不改变我们动作方法的代码基础上,对我们的动作方法进行增强。
 */
public class Hello3Action extends ActionSupport 
		implements ServletRequestAware,ServletResponseAware,ServletContextAware{

	private HttpServletRequest request;
	private HttpServletResponse response;
	private HttpSession session;
	private ServletContext application;
	/**
	 * @return
	 */
	public String sayHello(){
		
		session = request.getSession();
		
		System.out.println(request);
		System.out.println(response);
		System.out.println(session);
		System.out.println(application);
		return SUCCESS;
	}
	
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}
	@Override
	public void setServletContext(ServletContext application) {
		this.application = application;
	}
}

第四章 第4章请求参数的封装

4.1请求参数封装概述

封装请求参数就是把我们通过浏览器发送请求时,要转递给服务器的数据封装到指定的对象中。这个对象一般都是实体类。但是有时就是Action中的一个属性。
也就是说,我们封装请求参数时,可以有实体类,也可以没有。
同时,我们还需要知道,请求参数的封装和请求方式无关。无论get还是post都可以封装。

4.2属性驱动

4.2.1没有实体类(表单元素的name属性取值必须和动作类中的属性一致)

此种情况,我们一般也称为动作类和模型在一起,也就是说我们在action中定义一些私有成员,并且提供它们的公有get/set方法。具体代码如下图:
动作类:

/**
 * 请求参数的封装:
 * 	属性驱动:
 * 		没有独立的实体类(动作类和模型数据在一起)
 * 它要想封装成功,有如下要求:
 * 		表单元素的name属性取值必须和动作类中的属性一致(get/set方法后面的部分)
 *  
 * 细节:
 * 	struts2框架默认为我们解决了post请求的乱码问题。
 */
public class Demo1Action extends ActionSupport {

	private String name;
	private Integer age;
	
	public String demo1(){
		System.out.println(name+","+age);
		return SUCCESS;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}	
}

jsp页面:

<%--表单1:动作类模型在一起 --%>
<form action="${pageContext.request.contextPath}/demo1.action" method="post">
	用户名:<input type="text" name="name"/><br/>
	年龄:<input type="text" name="age"/><br/>
	<input type="submit" value="提交"/>
</form>

struts.xml

<action name="demo1" class="com.itheima.web.action.Demo1Action" method="demo1">
	<result name="success">/success.jsp</result>
</action>

以上这种方式需要通过在Action中定义属性,并且提供属性的set方法来完成。这种方式只需要提供set方法即可。但若需要传入的数据很多的话,那么Action的属性也会变得很多。再加上属性有对应的getter/setter方法,Action类的代码会很庞大,在Action里编写业务的代码时,会使Action非常臃肿,不够简洁。那么要怎样解决这个问题呢?
把属性和相应的getter/setter方法从Action里提取出来,单独作为一个值对象,这个对象就是用来封装这些数据的,在相应的Action里直接使用这个对象,而且可以在多个Action里使用。采用这种方式,一般以JavaBean来实现,所封装的属性和表单的属性一一对应,JavaBean将成为数据传递的载体。

4.2.2有实体类

此种情况是,我们有独立的实体类,在action中定义的是实体类对象,并且提供get/set方法。
代码如下:
先创建一个user类:动作类:

/**
 * 请求参数的封装:
 * 	属性驱动:
 *		动作类和模型数据分开
 * 使用要求:
 *  首先动作类中需要提供模型的get/set方法
 *  模型中要提供私有成员变量的get/set方法
 *  并且这些get/set方法必须和表单的name属性取值能对应上。
 * 
*/
public class Demo2Action extends ActionSupport {

	private User user = new User();
	
	public String demo2(){
		System.out.println(user);//输出有对象
		return SUCCESS;
	}

	public User getUser() {
		System.out.println("getUser");
		return user;
	}

	public void setUser(User user) {
		System.out.println("setUser");
		this.user = user;
	}
	
}

jsp页面:

<%--表单2:动作了和模型分开 
此时name属性的取值看上去是一个普通的字符串,但是实际上已经不是了。
而是一个OGNL表达式。
Object Graphic Navigation Language
对象		图		导航			语言
--%>
<form action="${pageContext.request.contextPath}/demo2.action" method="post">
	用户名:<input type="text" name="user.name"/><br/>
	年龄:<input type="text" name="user.age"/><br/>
	<input type="submit" value="提交"/>
</form>

struts.xml

<action name="demo2" class="com.itheima.web.action.Demo2Action" method="demo2">
	<result name="success">/success.jsp</result>
</action>

4.3模型驱动(表单输入项的属性值必须和实体类属性名一样)==============

在Struts2中,Action处理请求参数还有另外一种方式,叫做模型驱动(ModelDriven)。通过实现ModelDriven接口来接收请求参数。
此种封装方式必须按照要求编写代码,要求如下:
1、动作类必须实现ModelDriven接口
2、动作类中需要定义一个模型,并且必须实例化。
3、动作类提供ModelDriven接口中抽象方法的实现,返回模型对象。

注意:使用模型驱动时,get/set方法不是必须的。
动作类:

/**
 * 封装请求参数的第三种情况:
 * 	模型驱动
 *  
 * 使用要求:
 * 	1.动作类必须实现ModelDriven接口,其中泛型提供的是模型对象
 *   2.在动作类中需要定义一个模型对象,并且必须由我们自己来实例化
 *   3.提供接口中抽象方法的实现,方法的返回值是我们定义的模型对象
 *  模型驱动没有要求生成get/set方法
 * 
 * 实际开发中三种方式都有应用场景。
 * 在我们现阶段的学习中,以模型驱动作为重点。
 */
public class Demo3Action extends ActionSupport implements ModelDriven<User> {
	private User user = new User();

	@Override
	public User getModel() {
		return user;
	}
	public String demo3(){
		System.out.println(user);
		return SUCCESS;
	}
}

jsp页面:

<%--表单3:模型驱动 --%>
<form action="${pageContext.request.contextPath}/demo3.action" method="post">
	用户名:<input type="text" name="name"/><br/>
	年龄:<input type="text" name="age"/><br/>
	<input type="submit" value="提交"/>
</form>

struts.xml

<action name="demo3" class="com.itheima.web.action.Demo3Action" method="demo3">
	<result name="success">/success.jsp</result>
</action>

到这我们已经能够将数据封装到一个Java对象中了,大部分我们会优先使用模型驱动的方式,因为Struts2内部有很多结果是围绕模型驱动设计的。但如果页面向多个对象中封装,那么就需要使用属性驱动的方式二了。这些都是像某个对象中封装数据,那么如果Action中需要一个对象的集合呢?又应该如何进行数据的封装呢?那么接下来我们来了解一下Struts2中复杂类型数据的封装。

4.4封装集合数据

在实际的开发中,有些时候我们需要批量插入用户或者批量插入其他的对象,在Action中需要接受到这多个Action中封装的对象,然后传递给业务层。那么这个时候就需要将表单的数据封装到集合中。一般我们通常使用的集合无非是List或者是Map集合。下面就以这两种集合进行数据的封装的示例演示。

4.4.1封装到List

动作类:

/**
 * 封装集合数据:
 * 	它用的也是属性驱动
 */
public class Demo4Action extends ActionSupport {

	private List<User> users;
	
	public String demo4(){
		System.out.println(users);
		return SUCCESS;
	}

	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}	
}

jsp页面:

<%--表单4:封装List集合数据 --%>
<form action="${pageContext.request.contextPath}/demo4.action" method="post">
	用户名1:<input type="text" name="users[0].name"/><br/>
	年龄1:<input type="text" name="users[0].age"/><br/>
	用户名2:<input type="text" name="users[1].name"/><br/>
	年龄2:<input type="text" name="users[1].age"/><br/>
	用户名3:<input type="text" name="users[2].name"/><br/>
	年龄3:<input type="text" name="users[2].age"/><br/>
	<input type="submit" value="提交"/>
</form>

struts.xml

<action name="demo4" class="com.itheima.web.action.Demo4Action" method="demo4">
	<result name="success">/success.jsp</result>
</action>

4.4.2封装到Map

动作类:

/**
 * 封装集合数据:
 * 	它用的也是属性驱动
 * 
 */
public class Demo5Action extends ActionSupport {

	private Map<String,User> users;
	
	public String demo5(){
		System.out.println(users);
		return SUCCESS;
	}

	public Map<String, User> getUsers() {
		return users;
	}

	public void setUsers(Map<String, User> users) {
		this.users = users;
	}
}

jsp页面:

<%--表单5:封装map集合数据 --%>
<form action="${pageContext.request.contextPath}/demo5.action" method="post">
	用户名1:<input type="text" name="users['one'].name"/><br/>
	年龄1:<input type="text" name="users['one'].age"/><br/>
	用户名2:<input type="text" name="users['two'].name"/><br/>
	年龄2:<input type="text" name="users['two'].age"/><br/>
	用户名3:<input type="text" name="users['three'].name"/><br/>
	年龄3:<input type="text" name="users['three'].age"/><br/>
	<input type="submit" value="提交"/>
</form>

struts.xml

<action name="demo5" class="com.itheima.web.action.Demo5Action" method="demo5">
	<result name="success">/success.jsp</result>
</action>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值