一个Servlet处理多个请求

普通的Servlet一个Servlet只能处理一个请求,可以仿Struts1中的DispatchAction让一个Servlet处理多个请求。

做法是:

让普通处理请求的Servlet继承父类的BaseServlet,然后让父类单独继承HttpServlet.然后再在处理请求的servlet中定义自己的处理请求的方法,但方法中必须包HttpServletRequest,HttpServletResponse对象参数(方法名可以随意)。
我们在用户的请求地址上附加一个method参数,根据method参数的不同去调用不同的方法。注意在表单的action中附加请求参数时,如果使用的post请求时不会有任何问题的,但是一旦使用的get请求,由于get请求是通过url地址来传递请求参数的,所以get请求中的参数会自动覆盖掉action属性中的请求参数,所以如果使用get请求,那么action属性中的请求参数将会丢失所以我们在通过get方式发送请求时,需要在表单中设置一个表单隐藏域,并将method属性设置进隐藏域中。

BaseServlet类:

package cn.kgc.servlet.client;

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;
/**
 * BaseServlet[抽象类] 不需要在web.xml中添加路径
 * @功能 1. 
 * @author
 *
 */
public abstract class BaseServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	
	
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//		response.setContentType("text/html;charset=UTF-8");//处理响应编码
		/*
		 * 设置POST和GET请求编码
		 */				
		/*
		 * 1. 获取参数,用来识别用户想请求的方法
		 *      method是用户在浏览器地址栏中输入的想要调用的方法,是个参数
		 */
		String methodName = request.getParameter("method");
		//2. 判断用户有没有传入参数。
		if(methodName == null || methodName.trim().isEmpty()){
			throw new RuntimeException("您没有传递method参数! 无法确定您要调用的方法!");
		}
		/**
		 * 3. 判断是哪一个方法,是哪一个就调用哪一个
		 *    所用的技术是: 反射
		 *        需要得到本类Class,然后调用它的getMethod,通过传递过来的方法名字进行得到Method对象
		 *    这样做的目的是: 以后像其他Servlet中的方法要修改或者添加新方法时,就不用在去修改这一块代码了
		 */
		Method method = null ;
		try {
			/**
			 * method的结果:public java.lang.String cn.kgc.servlet.client.loOrreServlet.login(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
			 * 如下这句代码请注意两点:
			 * 1.因为getClass()在Object类中定义成了final,子类不能重写该方法,
			 * 所以这里的this调用的是Object类中的getClass()方法,等价于super,
			 * ( getClass()方法返回值为当前运行时类的Class对象,
			 * 所以 getClass()不受this和super影响,而是有当前的运行类决定的。)
			 * 2.getMethod()方法只能获取public修饰的方法,所以继承此类的servlet中的方法的访问修饰符必须是 public的
			 * 若想访问所有的方法,则把getMethod改成getDeclaredMethod
			 * 
			 */
			//3.1获取method方法
			method = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
		} catch (Exception e) {
			throw new RuntimeException("您要调用的方法"+methodName+",它不存在");
		} 
		try {
			/*
			 * 3.2. 调用method表示的方法,即: 调用继承该类的类中的方法
			 *     反射调用: 用this来调用method表示的方法,并且传递参数req和resp
			 *     result的返回值,是由继承此类的返回值决定,例如:return "f:/pages/user/login_success.jsp";
			 */
			String result =(String)method.invoke(this, request,response);
			System.out.println("result:"+result);
		    /**
		     * 4. 处理从继承这个类的类中返回的字符串(重定向和转发)
		     *     return "r:/index.jsp"; 和 return "f:/index.jsp";
		     *      返回的是字符串,需要解读字符串
		     */
			/*
			 * 4.1. 如果用户返回的字符串为null,或者"",那么什么都不做
			 */
			if(result == null || result.trim().isEmpty()){
				return  ;
			}
			/*
			 * 4.2. 解读字符串1:判断字符串中有没有冒号
			 *        没有冒号默认表示转发,反之再进行判断
			 */
			if(result.contains(":")){
				/*
				 * 4.3. 解读字符串2 : 先获取冒号位置,然后截取前缀(操作,是重定向还是转发)和后缀(路径)
				 */
				int index = result.indexOf(":");
				String operate = result.substring(0,index);
				String path = result.substring(index+1);
				/*
				 * 4.4. 进行处理,如果是r重定向,如果是f则转发
				 */
				if(operate.equalsIgnoreCase("r")){
					response.sendRedirect(request.getContextPath()+path);
				}else if(operate.equalsIgnoreCase("f")){
					request.getRequestDispatcher(path).forward(request, response);
				}else{
					throw new RuntimeException("您指定的操作"+operate+
							"不支持,请正确填写:r和f");
				}								
			}else{
				/*
				 * 没有冒号默认转发处理
				 */
				request.getRequestDispatcher(result).forward(request, response);
			}											
		} catch (Exception e) {
			System.out.println("您要调用的方法"+methodName+",它内部抛出了异常");
			throw new RuntimeException(e);
		}			
	}

	
}

post请求:

get请求:

servlet类,需要继承BaseServlet类

package cn.kgc.servlet.client;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.kgc.entity.User;
import cn.kgc.service.UserService;
import cn.kgc.service.impl.UserServiceImpl;
import cn.kgc.util.WebUtils;

@WebServlet("/loOrreServlet")
public class loOrreServlet extends BaseServlet {
	private static final long serialVersionUID = 1L;
	UserService us=new UserServiceImpl();

	//此方法中是由返回值的,也可以设置返回值类型void,最后请求转发或者重定向到目标页面
	public String login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			//此处getRequestBean是单独把参数封装成bean
			User bean = WebUtils.getRequestBean(request, User.class);
			//此处省略dao成相关的代码
			User login = us.login(bean);
			if(login!=null){
				HttpSession session = request.getSession();
				session.setAttribute("user",bean.getUsername());
				return "f:/pages/user/login_success.jsp";
			}else{
				return "r:/pages/user/login.jsp";
			}
		}
	
}

你可能感兴趣的:(Jsp/Servlet)