Servlet做Controller,实现一个类处理多个请求

https://my.oschina.net/Shawn1in/blog/759004

        传统的Servlet都是一个请求对应一个Servlet。

        例子如下:

请求:http://localhost:8080/ServletTest/Login

web.xml配置:

	<servlet>
		<servlet-name>Regist</servlet-name>
		<servlet-class>cn.xiaol.web.servlet.before.RegistServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Regist</servlet-name>
		<url-pattern>/Regist</url-pattern>
	</servlet-mapping>

Servlet代码:

public class RegistServlet extends HttpServlet {
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 重定向到regist页面
		response.sendRedirect(request.getContextPath() + "/regist.jsp");
	}

	// 在url上面测试是用Get方法请求,所以需要重写doGet()让它调用doPost()。
	// 也可以把doPost()中的代码直接写在doGet()
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
}

        所以当web项目很大时,请求也就很多,web.xml的配置量也就跟着变大,各种Servlet类爆增。

        于是我们可以通过反射的方式,将一类方法放在一个Servlet类中。例如User的增删改查请求可以放在一个UserServlet里面处理。

        下面做一个例子,将login和regist请求放在一个TestServlet中处理。但是在此之前需要先写一个父类BaseServlet,里面有一个利用反射原理实现的通过方法名调用对应方法的方法。挺绕口的。意思是这个BaseServlet继承HttpServlet,然后重写service()方法,因为每一个请求Servlet都会调用一次service方法,而这个service方法通过反射和请求中带的method参数可以调用自己类中对应的方法。

        一个完整的流程就是:

        第一步:请求http://localhost:8080/ServletTest/TestServlet?method=login

        第二步:子类TestServlet继承了BaseServlet,所以也继承了父类的service方法。一次请求触发一次service方法,于是service方法通过反射调用了TestServlet中的login方法。

        第三步:login方法处理完返回处理结果。

 

下面是例子:

请求:http://localhost:8080/ServletTest/TestServlet?method=login

1、http://localhost:8080/ServletTest/TestServlet是我们要请求的Servlet

2、method=login是我们要请求的Servlet中的方法

web.xml配置:

	<servlet>
		<servlet-name>TestServlet</servlet-name>
		<servlet-class>cn.xiaol.web.servlet.after.TestServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>TestServlet</servlet-name>
		<url-pattern>/TestServlet</url-pattern>
	</servlet-mapping>

BaseServlet代码:

package cn.xiaol.web.servlet.after;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BaseServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 1、获得方法名称
		String methodName = request.getParameter("method");
		Method method = null;

		// 2、通过方法名和方法所需要的参数获得Method对象
		try {
			method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
		} catch (Exception e) {
			throw new RuntimeException("调用的方法:" + methodName + "不存在", e);
		}

		// 3、通过Method对象调用方法
		try {
			String result = (String) method.invoke(this, request, response);
			if (result != null && result.trim().length() > 0) {// 如果返回的result不为空
				int index = result.indexOf(":");// 获得第一个冒号的位置
				if (index == -1) {// 如果没有冒号,就使用转发
					request.getRequestDispatcher(result).forward(request, response);
				} else {// 如果有冒号
					String start = result.substring(0, index);// 截取前缀
					String path = result.substring(index + 1);// 截取路径
					if (start.equalsIgnoreCase("f")) {// 前缀为f表示使用转发
						request.getRequestDispatcher(path).forward(request, response);
					} else if (start.equalsIgnoreCase("r")) {// 前缀为r表示使用重定向
						response.sendRedirect(request.getContextPath() + path);
					}
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

TestServlet代码:

package cn.xiaol.web.servlet.after;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @date 创建时间:2016年10月15日 上午11:59:25
 */
public class TestServlet extends BaseServlet {

	public String login(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("login");
		return "/login.jsp";
	}

	public String regist(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("regist");
		return "/regist.jsp";
	}
}

        当我们需要增加一个有关Test的请求时,我们可以直接在TestServlet中添加相关方法,而不比再写一个Servlet类。但是请求的时候记得要带上method方法参数。

        下面是Demo的完整代码

http://pan.baidu.com/s/1nvuEhBz

猜你喜欢

转载自blog.csdn.net/qq_16605855/article/details/80618992