struts(一)——jsp+Servlet讲解MVC框架基本原理

自从接触java一来,经常在论坛上看到一些大牛谈论框架云云,每每都觉得他们这些懂框架的都是真的大牛啊。羡慕嫉妒恨不能当饭吃,咱也跟随巨人的步伐,开始研究框架之旅。struts是所有框架中最简单、最经典的,从struts开始入手,算是一步捷径。


本篇作为预备篇,先从缘起缘灭开始吧——MVC基本原理。

MVC框架3个部分间的功能协作过程,已经很清楚了,不过这里可以再简单提一下:

               struts(一)——jsp+Servlet讲解MVC框架基本原理_第1张图片

1、终端用户发出一个请求,该请求到达Controller控制器。

2、控制器接受请求后,会检查该请求,然后决定使用什么业务逻辑来处理该请求,这时控制器会将该请求转发给一个相应的业务逻辑去处理;

3、模型中包含处理该用户请求的所有业务组件,并且也执行用户所需要的全部数据存取,代表终端用户查询检索出的任何数据都被打包返回给控制器。

4、控制器接受从模型返回的数据,并选择显示这些数据的相应的视图,并将视图返回给用户。


下面,先来采用一个不灵活的Servlet进行实现:

package com.xxjstgb.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String requestURI = request.getRequestURI();
                int start=requestURI.indexOf("/",1);
                int end=requestURI.indexOf(".");
                String path=requestURI.substring(start,end);		
                System.out.println("path=" + path);
		String username = request.getParameter("username");
		UserManager userManager = new UserManager();
		String forward = "";
		if ("/servlet/delUser".equals(path)) {
			userManager.del(username);
			forward = "/del_success.jsp";
		}else if ("/servlet/addUser".equals(path)) {
			userManager.add(username);
			forward = "/add_success.jsp";
		}else if ("/servlet/modifyUser".equals(path)) {
			userManager.modify(username);
			forward = "/modify_success.jsp";
		}else if ("/servlet/queryUser".equals(path)) {
			List userList = userManager.query(username);
			request.setAttribute("userList", userList);
			forward = "/query_success.jsp";
		}else {
			throw new RuntimeException("请求失败");
		}
		request.getRequestDispatcher(forward).forward(request, response);
       }
} 

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	
	<servlet>
		<servlet-name>TestServlet</servlet-name>
		<servlet-class>com.xxjstgb.servlet.testServlet</servlet-class>
	</servlet>
	 <servlet-mapping>
	 	<servlet-name>TestServlet</servlet-name>
	 	<url-pattern>*.do</url-pattern>
	 </servlet-mapping>
</web-app>


当用户发出请求时(比如请求为:http://localhost:8080/struts_dispatchaction/servlet/delUser.do),根据用户请求的具有一定特点的URL(该URL以/servlet/开头或者是*.do结尾),访问到相应的Servlet。

根据配置文件可知:这里配置的是以".do"结尾的请求,都能够访问到TestServlet。该Servlet又截取了每个请求中特有的部分"/servlet/delUser",根据这个串儿,调用相应的业务逻辑,并作相应的转向。


不过这种实现方式,大家一看便会觉得很不妥,这个Servlet的任务太重了。在这里调用了模型层逻辑,同时也进行了所有的页面转向。另外,包含了大量的if…else语句,由于业务的不稳定性,这里如果经常需要添加或者删除else语句的话,这将是一个非常糟糕的设计。


下面改良设计,我们将控制器细化为前端控制器TestServlet和业务控制器Action。


struts(一)——jsp+Servlet讲解MVC框架基本原理_第2张图片

前端控制器有两个任务:1、根据一定规则,截取url;2、根据url分发到相应的Action。

业务控制器负责:1、接受表单数据;2、调用业务逻辑;3、返回转向信息。

Action:

package com.xxjstgb.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
	public String execute(HttpServletRequest request, HttpServletResponse response)
	throws Exception;
}

delUserActiion:

package com.xxjstgb.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DelUserAction implements Action {
	public String execute(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
                //接收表单参数
                String username = request.getParameter("username");
		//调用业务逻辑
		UserManager userManager = new UserManager();
		try {
			userManager.del(username);
		}catch(Exception e) {
			return "del_error.jsp"; //转向路径可以通过配置文件读取
		}
                //转向信息
                return "/del_success.jsp"; //转向路径可以通过配置文件读取
	}
}

改良设计后的TestServlet:

package com.xxjstgb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String requestURI=request.getRequestURI();
		int start=requestURI.indexOf("/",1);
		int end=requestURI.indexOf(".");
		String path=requestURI.substring(start,end);
		Action action = null;
		if ("/servlet/delUser".equals(path)) {
			action = new DelUserAction();
		}else if ("/servlet/addUser".equals(path)) {
			action = new AddUserAction();
		}else if ("/servlet/modifyUser".equals(path)) {
			action = new ModifyUserAction();
		}else if ("/servlet/queryUser".equals(path)) {
			action = new QueryUserAction();
		}else {
			throw new RuntimeException("请求失败");
		}
		String forward = null;
		try {
			forward = action.execute(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		request.getRequestDispatcher(forward).forward(request, response);
	}
}

在这个Servlet中,已经将模型层的调用、页面转向分离到Action中。在具体的Action中负责调用模型层逻辑以及负责页面的转向。这就是MVC基本框架的简单实现。

时序图如下:

struts(一)——jsp+Servlet讲解MVC框架基本原理_第3张图片

尽管如此,这里主要的问题还是没有解决。这里仍然存在大量的if…else 结构,修改时,业务变更,仍然需要到这里来进行删减。

因此,我们可以在此基础上,将相应的action配置在配置文件里面,通过反射去掉if…else,这就是struts框架。后文介绍。

你可能感兴趣的:(mvc,框架,struts)