¶优化Servlet ⭐️⭐️⭐️
在开发过程中,完成一个模块时,如用户模块,会产生多个Servlet(注册,登录,登出等),为了减少Servlet文件的数量,将多个Servlet中的功能全部抽象为对应的方法,集合到一个Servlet中。
如图所示:BaseServlet用于实现方法的分发,关于用户的操作,将方法全部写在UserServlet中。
¶BaseServlet
重写HttpServlet中的service()方法,用于实现方法的分发。
- 通过获取URI,如:
/project/user/login
; - 使用字符串方法获取URI中最后的方法名,如
login
; - 使用反射机制获取对应的方法,如:
UserServlet.login()
; - 使用
invoke()
执行方法。
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//完成方法分发
//1.获取请求路径
String uri = req.getRequestURI();
//2.获取方法名称
String methodName = uri.substring(uri.lastIndexOf('/') + 1);
//3.获取方法对象
try {
Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//4.执行方法
method.invoke(this, req, resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
¶UserServlet
- 将之前实现各自功能的Servlet全部抽象成一个方法,如:
LoginServlet ->login()
,写入得到UserServlet中; - 需要将这些方法的修饰符从默认的
protected
修改为public
。因为在BaseServlet中调用getMethod()
执行对应方法,获取的是public方法,包括继承的方法,如果使用getDeclaredMethods()
,可以取得所有自己声明的方法,包括public protected default private
。 - 一些方法中多次定义使用的变量,如
UserService
,可以声明为UserServlet的成员变量。 - UserServlet的请求路径修改为
/User/*
,代表User下的所有方法都会请求该Servlet,然后根据方法名,调用父类BaseServlet中的service()
进行方法的分发执行。
@WebServlet(urlPatterns = "/User/*")
public class UserServlet extends BaseServlet {
private UserService userService = new UserServiceImpl();
/**
* 登录功能
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// UserService service = new UserServiceImpl();
User u = userService.login(user);
ResultInfo info = new ResultInfo();
if (u == null) {
info.setFlag(false);
info.setErrorMsg("用户名或密码错误!");
}
if (u != null && !"Y".equals(u.getStatus())) {
info.setFlag(false);
info.setErrorMsg("您尚未激活,清先激活!");
}
if (u != null && "Y".equals(u.getStatus())) {
request.getSession().setAttribute("user", u);
info.setFlag(true);
}
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json; charset=UTF-8");
mapper.writeValue(response.getOutputStream(), info);
}
}
¶修改相关路径
最后还需要在请求Servlet的地方将原来的路径修改为新的路径,如:/LoginServlet ->/User/login
。