普通的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请求:
<form action="${pageContext.request.contextPath}/loOrreServlet?method=login" method="post">
<!-- INPUT框信息 -->
</form>
get请求:
<form action="${pageContext.request.contextPath}/loOrreServlet?method=login" method="get">
<!-- 添加表单隐藏域-->
<input type="hidden" name="method" value="login"/>
</form>
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";
}
}
}