背景
还记得在刚开始学习JavaEE的时候,在使用Servlet时,一个Servlet只能处理一个请求,写在doGet
或是doPost
的方法中。这样会造成如果接口API多的话,会产生大量的Servlet文件,造成类爆炸,而且项目结构并不清晰。
解决办法是可以采用反射实现一个servlet处理多个接口请求。
反射实现一个servlet处理多个接口请求
代码
/**
* 测试使用反射,一个servlet处理多个接口请求
*
* @author rsw
*/
@WebServlet(name = "LoginServlet", value = "*.login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
System.out.println("servlet调用....");
//获取servletPath: /add.do 或 /query.do 等
String servletPath = request.getServletPath();
//去除/和.do : add 或 query
String methodName = servletPath.substring(1);
methodName = methodName.substring(0, methodName.length() - 6);
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
try {
//利用反射获取methondNmae对应的方法
Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//利用反射调用对应的方法
method.invoke(this, request, response);
} catch (Exception e) {
e.printStackTrace();
//response.sendRedirect("error.jsp"); //给用户提示
}
}
private void login ( HttpServletRequest request, HttpServletResponse response ) throws IOException, SQLException {
PrintWriter out = response.getWriter();
System.out.println("正在尝试登录...");
//输出到页面
out.println("正在尝试登录...");
}
private void exitLogin ( HttpServletRequest request, HttpServletResponse response ) throws IOException, SQLException {
//获取请求参数
PrintWriter out = response.getWriter();
System.out.println("正在尝试退出...");
//输出到页面
out.println("正在尝试退出...");
}
}
解析
- 注解
@WebServlet(name = "LoginServlet", value = "*.login")
的value为*.login
;截取接口的访问路径如果携带.login
,那么则会进入到LoginServlet
。 - 字符串截取:
*.login
中的*
代表的是在当前servlet的方法,通过匹配方法的方式,来实现使用接口API调用servlet中的指定的方法。
//去除/和.do : add 或 query
String methodName = servletPath.substring(1);
methodName = methodName.substring(0, methodName.length() - 6);
.login
为6个字符,所以减去6。
3. 使用反射调用指定的方法
//利用反射获取methondNmae对应的方法
Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//利用反射调用对应的方法
method.invoke(this, request, response);
HttpServletRequest.class
和HttpServletResponse.class
为调用方法的参数类型,一般都需要request和response,不管使用不,这里默认都使用。
4. login
和exitLogin
为两个测试的方法
注意:这里value
的*.login
只是测试使用,login
可以是任意字符,但必须要根据字符个数修改methodName.substring(0, methodName.length() - 6)
。
使用示例
配置tomcat略…
控制台输出:
servlet调用....
正在尝试登录...
控制台输出:
servlet调用....
正在尝试退出...
总结
使用反射实现一个servlet处理多个接口请求,如果想要添加一个接口的API就不必再新增一个servlet文件了,直接添加方法就可以了。