Struts2(1前述及搭建环境)

Struts2_使用 Filter 作为控制器的 MVC 应用

实现 MVC(Model、View、Controller) 模式的应用程序由 3 大部分构成:
模型:封装应用程序的数据和业务逻辑POJO(Plain Old Java Object)// 普通的java类
**视图:**实现应用程序的信息显示功能JSP
**控制器:**接收来自用户的输入,调用模型层,响应对应的视图组件Servlet Filter
背景
在这里插入图片描述
代码
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="product-input.action">Product Input</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="product-save.action" method="post">
		
		ProductName: <input type="text" name="productName"/>
		<br><br>

		ProductDesc: <input type="text" name="productDesc"/>
		<br><br>
		
		ProductPrice: <input type="text" name="productPrice" />
		<br><br>
		
		<input type="submit" value="Submit"/>
		<br><br>
	
	</form>

</body>
</html>

product

public class Product {
	
	private Integer productId;
	private String productName;
	private String productDesc;
	
	private double productPrice;

	public Integer getProductId() {
		return productId;
	}

	public void setProductId(Integer productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public String getProductDesc() {
		return productDesc;
	}

	public void setProductDesc(String productDesc) {
		this.productDesc = productDesc;
	}

	public double getProductPrice() {
		return productPrice;
	}

	public void setProductPrice(double productPrice) {
		this.productPrice = productPrice;
	}

	public Product(Integer productId, String productName, String productDesc,
			double productPrice) {
		super();
		this.productId = productId;
		this.productName = productName;
		this.productDesc = productDesc;
		this.productPrice = productPrice;
	}
	
	public Product() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "Product [productId=" + productId + ", productName="
				+ productName + ", productDesc=" + productDesc
				+ ", productPrice=" + productPrice + "]";
	}
	
	
}

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>Insert title here</title>
</head>
<body>
	
	ProductId: ${requestScope.product.productId }
	<br><br>

	ProductName: ${requestScope.product.productName }
	<br><br>
	
	ProductDesc: ${requestScope.product.productDesc }
	<br><br>
	
	ProductPrice: ${requestScope.product.productPrice }
	<br><br>
	
</body>
</html>

FilterDispatcher



import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * Servlet Filter implementation class FilterDispatcher
 */
public class FilterDispatcher implements Filter {

	public void destroy() {}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest req = (HttpServletRequest) request;
		
		//1. 获取 servletPath
		String servletPath = req.getServletPath();
		System.out.println(servletPath);
		
		String path = null;
		
		//2. 判断 servletPath, 若其等于 "/product-input.action", 则转发到
		///WEB-INF/pages/input.jsp
		if("/product-input.action".equals(servletPath)){
			path = "/WEB-INF/pages/input.jsp";
		}
		
		//3. 若其等于 "/product-save.action", 则
		if("/product-save.action".equals(servletPath)){
			//1). 获取请求参数
			String productName = request.getParameter("productName");
			String productDesc = request.getParameter("productDesc");
			String productPrice = request.getParameter("productPrice");
			
			//2). 把请求信息封装为一个 Product 对象
			Product product = new Product(null, productName, productDesc, Double.parseDouble(productPrice));
			
			//3). 执行保存操作
			System.out.println("Save Product: " + product);
			product.setProductId(1001);
			
			//4). 把 Product 对象保存到 request 中. ${param.productName} -> ${requestScope.product.productName}
			request.setAttribute("product", product);
			
			path = "/WEB-INF/pages/details.jsp";
		}
		
		if(path != null){
			request.getRequestDispatcher(path).forward(request, response);
			return;
		}
		
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {}

}

使用 Filter 作为控制器的好处
使用一个过滤器来作为控制器, 可以方便地在应用程序里对所有资源(包括静态资源)进行控制访问.
Servlet Filter比较
Servlet 能做的 Filter 都可以完成
Filter 能做的 Servlet 不可以完成, 拦截资源却不是 Servlet 所擅长的! Filter 中有一个 FilterChain,这个 API 在 Servlet 中没有!

Struts2概述

Struts2 是一个用来开发 MVC 应用程序的框架. 它提供了 Web 应用程序开发过程中的一些常见问题的解决方案:
对来自用户的输入数据进行合法性验证
统一的布局
可扩展性
国际化和本地化
支持 Ajax
表单的重复提交
文件的上传下载
……

Struts2和Struts1相比

在体系结构方面更优秀:
类更少, 更高效: 在 Struts2 中无需使用 “ActionForm” 来封装请求参数.
扩展更容易: Struts2 通过拦截器完成了框架的大部分工作. 在 Struts2 中插入一个拦截器对象相当简便易行.
更容易测试:
即使不使用浏览器也可以对基于 Struts2 的应用进行测试

Struts1 升级到 Struts2

Struts2 从本质上讲已不是从 Struts1 扩展而来的, 说它是一个换了品牌标签的 WebWork 更合适
从 Struts1 升级到 Struts2:
Struts1 里使用 ActionServlet 作为控制器; Struts2 使用了一个过滤器作为控制器
Struts1 中每个 HTML 表单都对应一个 ActionForm 实例. Struts2 中, HTML 表单将被直接映射到一个 POJO.
Struts1 的验证逻辑编写在 ActionForm 中; Struts2 中的验证逻辑编写在 Action 中.
Struts1 中, Action 类必须继承 org.apache.struts.action.Action 类; Struts2 中任何一个 POJO 都可以是一个 Action 类.
Struts2 在页面里使用 OGNL 来显示各种对象模型, 可以不再使用 EL 和 JSTL

下载 Struts2

struts-2.3.x-all.zip

Hello World

搭建 Struts2 的环境:

具体教程
加入 jar 包: 复制 struts\apps\struts2-blank\WEB-INF\lib 下的所有 jar 包到当前 web 应用的 lib 目录下.
在 web.xml 文件中配置 struts2: 复制 struts\apps\struts2-blank1\WEB-INF\web.xml 文件中的过滤器的配置到当前 web 应用的 web.xml 文件中
在当前 web 应用的 classpath 下添加 struts2 的配置文件 struts.xml: 复制 struts1\apps\struts2-blank\WEB-INF\classes 下的 struts.xml 文件到当前 web 应用的 src 目录下.

添加 DTD 约束
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
struts-2.3.4-all\struts-2.3.4\src\core\src\main\resources
在这里插入图片描述
在这里插入图片描述

代码详情

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>

	<!--  
		package:. struts2 使用 package 来组织模块. 
		name 属性: 必须. 用于其它的包应用当前包. 
		extends: 当前包继承哪个包, 继承的, 即可以继承其中的所有的配置. 通常情况下继承 struts-default
		         struts-default 这个包在 struts-default.xml 文件中定义.
		namespace 可选, 如果它没有给出, 则以 / 为默认值. 
		                        若 namespace 有一个非默认值, 则要想调用这个包里的Action, 
		                        就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里
		                        
		          http://localhost:8080/contextPath/namespace/actionName.action
	-->
    <package name="helloWorld" extends="struts-default">
    	
    	<!-- 
    		配置一个 action: 一个 struts2 的请求就是一个 action 
    		name: 对应一个 struts2 的请求的名字(或对一个 servletPath, 但去除 / 和扩展名), 不包含扩展名
    		class 的默认值为: com.opensymphony.xwork2.ActionSupport
    		method 的默认值为: execute
    		result: 结果. 
    	-->
    	<action name="product-input" 
    		class="com.opensymphony.xwork2.ActionSupport"
    		method="execute">
    		<!--  
    			result: 结果. 表示 action 方法执行后可能返回的一个结果. 所以一个 action 节点可能会有多个 result 子节点.
    			多个 result 子节点使用 name 来区分
    			name: 标识一个 result. 和 action 方法的返回值对应. 默认值为 success
    			type: 表示结果的类型. 默认值为 dispatcher(转发到结果.)
    		-->
    		<result name="success" type="dispatcher">/WEB-INF/pages/input.jsp</result>
    	</action>
    	
    	<action name="product-save" class="com.atguigu.struts2.helloworld.Product"
    		method="save">
    		<result name="details">/WEB-INF/pages/details.jsp</result>	
    	</action>
    	
    	<action name="test" class="com.atguigu.struts2.helloworld.Product" method="test">
    		<result>/index.jsp</result>
    	</action>
    	
    </package>

</struts>


src/product Product

package product;

public class Product {
	
	private Integer productId;
	private String productName;
	private String productDesc;
	
	private double productPrice;

	public Integer getProductId() {
		return productId;
	}

	public void setProductId(Integer productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public String getProductDesc() {
		return productDesc;
	}

	public void setProductDesc(String productDesc) {
		this.productDesc = productDesc;
	}

	public double getProductPrice() {
		return productPrice;
	}

	public void setProductPrice(double productPrice) {
		this.productPrice = productPrice;
	}

	

	@Override
	public String toString() {
		return "Product [productId=" + productId + ", productName="
				+ productName + ", productDesc=" + productDesc
				+ ", productPrice=" + productPrice + "]";
	}
	public String save(){
		System.out.println("save:"+this);
		return "details";
	}
	
}

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="product-input.action">Product Input</a>
	
</body>
</html>

WEB.INF/pages

details.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>
	
	ProductId: ${productId }
	<br><br>

	ProductName: ${productName }
	<br><br>
	
	ProductDesc: ${productDesc }
	<br><br>
	
	ProductPrice: ${productPrice }
	<br><br>
	
</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="product-save.action" method="post">
		
		ProductName: <input type="text" name="productName"/>
		<br><br>

		ProductDesc: <input type="text" name="productDesc"/>
		<br><br>
		
		ProductPrice: <input type="text" name="productPrice" />
		<br><br>
		
		<input type="submit" value="Submit"/>
		<br><br>
	
	</form>

</body>
</html>

实现总结:

1). 搭建 Struts2 的开发环境
2). 不需要显式的定义 Filter, 而使用的是 struts2 的配置文件.
3). details.jsp 比先前变得简单了.
${requestScope.product.productName} -> ${productName}

4). 步骤:
I. 由 product-input.action 转到 /WEB-INF/pages/input.jsp
在 struts2 中配置一个 action

/WEB-INF/pages/input.jsp

II. 由 input.jsp 页面的 action: product-save.action 到 Product’s save, 再到 /WEB-INF/pages/details.jsp

<action name="product-save" class="com.atguigu.struts2.helloworld.Product"
		method="save">
		<result name="details">/WEB-INF/pages/details.jsp</result>	
	</action>

在 Prodcut 中定义一个 save 方法, 且返回值为 details
struts2.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>

	<!--  
		package:. struts2 使用 package 来组织模块. 
		name 属性: 必须. 用于其它的包应用当前包. 
		extends: 当前包继承哪个包, 继承的, 即可以继承其中的所有的配置. 通常情况下继承 struts-default
		         struts-default 这个包在 struts-default.xml 文件中定义.
		namespace 可选, 如果它没有给出, 则以 / 为默认值. 
		                        若 namespace 有一个非默认值, 则要想调用这个包里的Action, 
		                        就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里
		                        
		          http://localhost:8080/contextPath/namespace/actionName.action
	-->
    <package name="helloWorld" extends="struts-default">
    	
    	<!-- 
    		配置一个 action: 一个 struts2 的请求就是一个 action 
    		name: 对应一个 struts2 的请求的名字(或对一个 servletPath, 但去除 / 和扩展名), 不包含扩展名
    		class 的默认值为: com.opensymphony.xwork2.ActionSupport
    		method 的默认值为: execute
    		result: 结果. 
    	-->
    	<action name="product-input" 
    		class="com.opensymphony.xwork2.ActionSupport"
    		method="execute">
    		<!--  
    			result: 结果. 表示 action 方法执行后可能返回的一个结果. 所以一个 action 节点可能会有多个 result 子节点.
    			多个 result 子节点使用 name 来区分
    			name: 标识一个 result. 和 action 方法的返回值对应. 默认值为 success
    			type: 表示结果的类型. 默认值为 dispatcher(转发到结果.)
    		-->
    		<result name="success" type="dispatcher">/WEB-INF/pages/input.jsp</result>
    	</action>
    	
    	<action name="product-save" class="com.atguigu.struts2.helloworld.Product"
    		method="save">
    		<result name="details">/WEB-INF/pages/details.jsp</result>	
    	</action>
    	
    	<action name="test" class="com.atguigu.struts2.helloworld.Product" method="test">
    		<result>/index.jsp</result>
    	</action>
    	
    </package>

</struts>

猜你喜欢

转载自blog.csdn.net/feiqipengcheng/article/details/106424591