第一张 结果视图的配置
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>