基于 MVC 的三层架构
web层(表示|界面层)、service层(业务逻辑层)、dao层(数据访问层、持久层)
/*
* 写三层有两种方式:
* 从前往后写:简单,没有多余的方法
* 从后往前写:对开发者要求高,所有的dao都要写
*/
从图中可以看出 servlet 的压力很大,既要与业务逻辑的交互,又要处理请求,同时还负责jsp页面的显示。严格按照MVC三层模型的写法的情况下,servlet会非常多,还有相当一部分只做 jsp 页面的展示。
在实际的项目中,jsp 页面的展示一般就不会再用servlet处理了,另外在处理请求方面,servlet 是可以被简化的。
- 一个 servlet 实现多个请求:
jsp 请求写法:${pageContext.request.contextPath }/userservlet?method=login
servlet 写法:用反射实现了 servlet 类中方法的调用,使一个 servlet 可以处理多个请求。大大减少 servlet 的数量。
@WebServlet(name = "UserServlet",urlPatterns = "/userservlet")
public class UserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String methodName = request.getParameter("method");
// if(methodName.equals("register")){
// register(request, response);
// }else if (methodName.equals("login")){
// login(request, response);
// }
try {
Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
if(method != null){
method.invoke(this,request,response);
}
} catch (Exception e) {
throw new RuntimeException("没有调用的方法", e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void register(HttpServletRequest request,HttpServletResponse response){
System.out.println("注册了");
}
public void login(HttpServletRequest request,HttpServletResponse response){
System.out.println("登录了");
}
}
- Servlet父类:
把上边这个类进行抽象,封装父类,项目中所有 servlet 继承父类,配置每个 servlet 类的路径后,直接在 servlet 类中写方法即可
//所有servlet的父类,不要写注解
public class BaseServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String methodName = request.getParameter("method");
try {
Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
if(method != null) {
String url = (String) method.invoke(this, request, response);
if(!url.isEmpty()){
if(url.startsWith("redirect:")){
String realURL = url.split(":")[1];
//重定向
response.sendRedirect(request.getContextPath()+"/"+realURL);
}else {
//转发
request.getRequestDispatcher(url).forward(request, response);
}
}
}
} catch (NoSuchMethodException |IllegalAccessException |InvocationTargetException e) {
throw new RuntimeException("没有相关方法", e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
- 优化的 servlet:
@WebServlet(name = "admin.UserServlet",urlPatterns = "/admin/userservlet")
public class UserServlet extends BaseServlet {
//删除用户
public String deleteUser(HttpServletRequest request,HttpServletResponse response){
//判断是否登录
User admin = (User)request.getSession().getAttribute("admin");
if(admin == null){
return "redirect:admin/login.jsp";
}
//2.获取参数
String id = request.getParameter("id");
UserService userService = new UserServiceImpl();
boolean b = userService.updateFlag(Integer.parseInt(id),2);
if(!b){
throw new RuntimeException("删除用户失败");
}
return null;
}
//用户登录
public String login(HttpServletRequest request,HttpServletResponse response){
String username = request.getParameter("username");
String password = request.getParameter("password");
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
throw new RuntimeException("用户名或密码为空");
}
UserService userService = new UserServiceImpl();
User user = userService.login(username, password);
if(user != null){
if(user.getRole() == 1){//管理员
request.setAttribute("msg", "请用管理员账号登录");
return "/admin/login.jsp";
}
}else {
request.setAttribute("msg", "用户名或密码不正确");
return "/admin/login.jsp";
}
//放入Session
request.getSession().setAttribute("admin", user);
return "redirect:admin/admin.jsp";
}