1.struts2是什么?
struts2是一个用来开发MVC应用程序的框架,他为MVC模式开发提供一套标准,解决了web应用程序开发过程中的一些常见问题。例如对用的输入数据进行合法的验证,统一的布局,可拓展性,
国际化和本地化,支持ajax,表单的重复提交,文件的上传和下载等。
2.struts2的运行原理如图所示:
可以看的出来struts2框架和之前我们学习的之前理解的MVC大有不同。之前充当控制器的都是我们的Servlet,而在Struts2框架中由filter(C)作为总控制器,对浏览器所有的请求做出拦截,并且到其配置的struts.xml中找到我们的action处理类(C和M),由action处理请求和逻辑业务,处理完请求通过action处理的结果找到对应的result(V)返回给浏览器。从上图能很清晰的看到struts2对MVC的严格定义和规范。
3.struts2的简单环境搭配
①.引入jar包,这个到官网下载全套的jar解压,引入web工程即可,这里不过多解释。引入struts2的官方jar包就是为了使用其定义的web框架的MVC标准。环境搭建完成图如下:
②.配置web.xml,这里配置web.xml主要是为了配置struts2框架中的一个重要的角色就是总控制器(StrutsPrepareAndExecuteFilter)。其会拦截所有的请求,并且到其配置的struts.xml中找到对应的action做
相应的处理和存储。配置图如下:
③.配置struts.xml。struts.xml配置是整个MVC中一个至关重要的角色。首先其应该放在项目src目录下面的,创建图如下:
那么我们应该如何来配置我们的struts.xml如何将请求和一个action建立联系呢?
我们通过一个简单的案例来说明,案列的页面有如下几个:
首页index.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>
<a href="/StrutsTest2/product-input.action">Product-input.jsp</a>
</body>
</html>
输入页input.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>
<form action="/StrutsTest2/product-detail.action" method="post">
商品名:<input type="text" name="name"/><br><br>
价格:<input type="number" name="price" min="1"/><br><br>
商品名:<input type="text" name="des"/><br><br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
显示页detail.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>商品细节展示</title>
</head>
<body>
ProductName:${name }<br/><br/>
ProductPrice:${price }<br/><br/>
ProductDescribe:${des }<br/><br/>
</body>
</html>
action类Product如下:
package com.yd.bean;
import java.io.Serializable;
public class Product implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private Double price;
private String des;
public Product() {
super();
}
public Product(String name, Double price, String des) {
super();
this.name = name;
this.price = price;
this.des = des;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((des == null) ? 0 : des.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((price == null) ? 0 : price.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Product other = (Product) obj;
if (des == null) {
if (other.des != null)
return false;
} else if (!des.equals(other.des))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (price == null) {
if (other.price != null)
return false;
} else if (!price.equals(other.price))
return false;
return true;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + ", des=" + des + "]";
}
public String save(){
return "detail";
}
}
文件的创建位置如下图:
struts.xml配置图如下:
①首先说说pakage标签,package包用来组织模块的,例如一个系统中有用户模块,商家模块那么就可以通过package来分别管理。
name属性是给package起一个名字,可以用于给别的模块继承,这样别的package就拥有其所有的配置。
extends属性是用于继承其他包的,一般我们继承struts-default包,其位于struts的jar包中的struts-core目录下的struts-default.xml中。在其中可以看到struts-defalut包的一些配置。例如action的默认类为ActionSupport.
namesapce属性是定义命名空间的,如果没有给出则以‘/’为默认值也就是当前web应用下,如果namespace有值,则想要调用这个package中的action,那么在请求action时就需要在之前加上该属性的值。
例如:http://localhost:8080/web应用名/namespace/action的名字.action
②那么接下来说说我们的action,action是用来做请求处理的,以及请求参数存储的。
name属性指的是servletPath的值(不包含/ 和 拓展名)
class属性是指请求处理类的位置,如果不设置将使用继承的struts-default包下的ActionSupport来处理。如果设置了,通过设置这个运行时类利用反射机制,将请求参数设置到该action对象中,这里有一点需要主要的,参数名字name要和action类的setName()方法要一致,这样才能将参数设置进去。
例如表单提交的数据如下:
那么action对应的处理类中的set,get方法名也要与其对应才能通过反射机制将值设置到action对象中去,action方法名为如下图:
method属性是通过调用action对象的method方法返回的值,和result标签中的name中的值对应那么就返回对应的result.
③resul标签设置请求处理结果。所以一个action标签中可以对应多个result子节点,多个result子节点通过name属性来区分。
其name属性值和action中method方法的返回值对应。
type属性是设置跳转到result结果的类型,例如转发过去或者是重定向过去等。其默认值为dispatcher(转发)。
案例说明,index.jsp中请求product-input.action则被第一个action处理,result跳转到input.jsp.然后输入表单内容提交请求product-detail.action被第二个action处理,并且参数值被设置到了Product对象中。
最后跳转到了detail.jsp页面。