为什么需要一个servlet处理多个请求
- 在web.xml中一个servlet只能绑定一个url-pattern,如果一个servlet只处理一个请求的话,业务一多这种写法就会效率非常低下。并且会浪费更多的资源。
解决思路
- 每次请求servlet都会调用它的service()方法那么我们只需要重写servlet的service方法。前端将此次请求需要调用的方法名通过参数传递过来。在service中获取此方法名并通过反射来调用此方法
- 前端传递参数参数名为 method 参数内容为此次请求所要调用的方法名
代码实现
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;
//自己的servlet可以继承BaseServlet;
public class BaseServlet extends HttpServlet {
//重写service方法
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");//处理响应编码
//获取此次请求所要调用的方法名
String methodName = request.getParameter("method");
// 判断用户有没有传入参数。
if(methodName == null || methodName.trim().isEmpty()){
throw new RuntimeException("您没有传递method参数! 无法确定您要调用的方法!");
}
Method method = null ;
try {
//获取method方法
method = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
} catch (Exception e) {
throw new RuntimeException("您要调用的方法"+methodName+",它不存在");
}
try {
//通过反射执行方法 方法会返回字符串通过返回的字符来确定(重定向和转发)。
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);
}
}
}
- 使用时只需让自己的servlet继承Baseservlet