執行流程及分析(個人理解):
BaseServlet的抽取其實就是將每個Servelt封裝成爲每一個模塊功能到到一個類中.此類繼承BaseServlet類,BaseServlet繼承HttpServlet,再根據Servlet的生命週期,會執行service方法,所以在BaseServlet中重寫service方法,再在service方法中通過反射去執行到每個具體的Servlet類中的每個模塊功能。
好處:最主要的是代碼後期的維護性增強,讓web層中的servlet更簡潔。另外高內聚、低耦合,代碼得複用性也得到了很大的體現
下面以一個用戶登錄的案例爲例:
BaseServlet
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//1.獲取請求的uri
String uri = req.getRequestURI();
System.out.println("請求的uri : " + uri); //travel/find
//2.獲取方法名稱
String methodName = uri.substring(uri.lastIndexOf("/")+1);
System.out.println(methodName);
System.out.println(this);
//3.獲取方法的對象
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();
}
}
/**
* 代碼優化,將錯誤信息對象轉化爲json字符串
* @param flag
* @param msg
* @return
*/
public String getJson(boolean flag , String msg){
try {
ResultInfo resultInfo = new ResultInfo();
resultInfo.setFlag(flag);
resultInfo.setErrorMsg(msg);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(resultInfo);
return json;
} catch (JsonProcessingException e) {
System.out.println("異常!");
return null;
}
}
/**
* 重載形式
* @param flag
* @return
*/
public String getJson(boolean flag){
try {
ResultInfo resultInfo = new ResultInfo();
resultInfo.setFlag(flag);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(resultInfo);
return json;
} catch (JsonProcessingException e) {
System.out.println("異常!");
return null;
}
}
UserServlet
@WebServlet("/userServlet/*")
public class UserServlet extends BaseServlet{
/**
* 用戶登錄
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void userLogin(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
resp.setContentType("text/html;charset=utf-8");
//獲取頁面用戶輸入的驗證碼
String check = req.getParameter("check");
HttpSession session = req.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
//驗證碼校驗
if (checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)) {
/*resultInfo.setFlag(false);
resultInfo.setErrorMsg("登錄失敗,驗證碼錯誤!");
String json = mapper.writeValueAsString(resultInfo);*/
String json = super.getJson(false , "登錄失敗,驗證碼錯誤!");
resp.getWriter().write(json);
return;
}
//用戶名密碼校驗
String username = req.getParameter("username");
String password = req.getParameter("password");
UserService userService = new UserServiceImpl();
User user = userService.findByUsernameAndPassword(username, password);
if (user == null) {
//用戶名和密碼錯誤 響應信息
String json = super.getJson(false , "登錄失敗,用戶名或者密碼錯誤");
resp.getWriter().write(json);
return;
}
//繼續判斷用戶的賬號是否激活
if(user.getStatus().equals("N")){
//沒有激活,給出提示
String json = super.getJson(false , "登錄失敗,您尚未激活!");
resp.getWriter().write(json);
return;
}else {
//執行到此處證明所有條件滿足
session.setAttribute("userLogin",user);
String json = super.getJson(true);
resp.getWriter().write(json);
}
}
/**
* 用戶註冊
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void register(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
resp.setContentType("text/html;charset=utf-8");
//首先對驗證碼進行校驗
//*獲取用戶輸入的驗證碼
String check = req.getParameter("check");
System.out.println(check);
//*獲取服務器端會話中的驗證碼
HttpSession session = req.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
//爲了保證一次性質驗證碼,在獲取之後直接刪除會話中的驗證碼
ObjectMapper mapper = new ObjectMapper();
ResultInfo resultInfo = new ResultInfo();
if(checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)){
String json = super.getJson(false , "註冊失敗!驗證碼錯誤!");
//將錯誤信息反饋給頁面
resp.getWriter().print(json);
return;
}
//獲取頁面註冊的參數
Map<String, String[]> parameterMap = req.getParameterMap();
User user = new User();
//封裝對象
BeanUtils.populate(user , parameterMap);
/** 測試 */
System.out.println(user);
//調用service層
UserService userService = new UserServiceImpl();
boolean flag = userService.register(user);
String json = null;
if(flag == true){
//註冊成功
json = super.getJson(true);
}else {
json = super.getJson(false , "註冊失敗!用戶名存在!");
}
//將json反饋給html頁面
resp.getWriter().print(json);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 用戶激活
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void activeUser(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取激活碼
String code = req.getParameter("code");
UserService userService = new UserServiceImpl();
System.out.println(code);
boolean flag = userService.active(code);
String msg = null;
if(flag == true){
//激活成功
msg = "激活成功,您現在可以<a href='http://localhost:8080/travel/login.html'>登錄</a>";
}else {
//激活失敗
msg = "激活失敗,請聯繫管理員";
}
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(msg);
}
/**
* 用戶退出
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void exit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("退出");
//銷燬session
req.getSession().invalidate();
//跳轉到登錄的頁面
resp.sendRedirect(req.getContextPath() + "/login.html");
}
/**
* 判斷用戶是否已登錄
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void findUserSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(1212);
//首先獲取會話中的登錄賬戶
Object userLogin = req.getSession().getAttribute("userLogin");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(userLogin);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(json);
}
User類省略…
![在這裏插
訪問此路徑就相當於執行了UserServet中的register模塊,從而實現了註冊的功能。這樣是不是大大方便了很多,不用去寫很多的servlet頁面了呢?
至於底層的原理,主要就是反射機制、繼承以及Servlet的生命週期。就不一一介紹了,大家可以去看看源碼!