登陸中的異常處理(對比之前處理方式)
阿新 • • 發佈:2019-01-04
利用spring框架提供的處理方式來處理異常(使用@ExceptionHandler註解)
登入controller處理器:
package com.tarena.netctoss.controller; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.tarena.netctoss.entity.Admin; import com.tarena.netctoss.exception.BaseController; import com.tarena.netctoss.service.LoginService; @Controller public class LoginController extends BaseController{ @Resource(name="loginService") private LoginService service; @RequestMapping("/toLogin.do") public String toLogin(){ return "login"; } @RequestMapping("/login.do") //登入成功-重定向到首頁 public String login(HttpServletRequest request, HttpSession session){ //jsp頁面採用的是post提交 可以使用以下編碼,預防中文亂碼 //request.setCharacterEncoding("UTF-8"); String adminCode = request.getParameter("adminCode");//賬號 String pwd = request.getParameter("pwd");//賬號 System.out.println(adminCode + " " + pwd); //呼叫業務層服務--此處要處理異常 //採用註解(spring框架)來處理異常 Admin admin = service.checkLogin(adminCode, pwd); //把admin物件繫結到session,用於session驗證(位於攔截器) session.setAttribute("admin", admin); return "redirect:toIndex.do"; } @RequestMapping("/toIndex.do") //首頁 public String toIndex(){ return "index"; } }
業務層程式碼:
/** * 業務層實現 */ @Service("loginService") public class LoginServiceImpl implements LoginService{ @Resource(name="adminDAO") private AdminDAO dao; public Admin checkLogin(String adminCode, String pwd) { Admin admin = null; admin = dao.findByAdminCode(adminCode); if(admin == null){ //賬號不存在 //丟擲一個應用異常(使用者操作引起的異常) throw new ApplicationException("賬號不存在"); } if(!admin.getPassword().equals(pwd)){ //密碼不正確 throw new ApplicationException("密碼錯誤"); } //登入成功 return admin; } }
持久層程式碼:
package com.tarena.netctoss.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.stereotype.Repository; import com.tarena.netctoss.entity.Admin; /** * 持久層實現 */ @Repository("adminDAO") public class AdminDAOJdbcImpl implements AdminDAO{ //通過依賴注入將連線池注入(DataSource是介面 無論是絕對不是還是c3p0) @Resource(name="ds") private DataSource ds; public Admin findByAdminCode(String adminCode) { Admin admin = null; Connection conn = null; try { conn = ds.getConnection(); String sql = "select * from admin_info where admin_code=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, adminCode); ResultSet rs = ps.executeQuery(); if(rs.next()){ admin = new Admin(); admin.setAdminId(rs.getInt("admin_id")); admin.setAdminCode(rs.getString("admin_code")); admin.setPassword(rs.getString("password")); admin.setName(rs.getString("name")); admin.setTelephone(rs.getString("telephone")); admin.setEmail(rs.getString("email")); admin.setEnrolldate(rs.getTimestamp("enrolldate")); } } catch (SQLException e) { //記錄日誌 e.printStackTrace();//列印到控制檯 /* * 看異常能否恢復,若能恢復,則立即恢復 * 若不能恢復(例:系統異常,資料庫發生異常),則提示使用者稍後重試 */ //此處異常拋給業務層 throw new RuntimeException(e); } finally { if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e);//此處異常拋給業務層 } } } return admin; } }
最終在controller中要處理業務層和持久層所丟擲的異常,案例中有兩種,ApplicationException和RuntimeException
處理方式如下:
此時將登入方法中的try...catch去掉,可以和部落格之前的程式碼比較,將異常交給spring處理
寫一個處理異常的類,可以讓登入controller整合該類:
package com.tarena.netctoss.exception;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.tarena.netctoss.service.ApplicationException;
public class BaseController{
@ExceptionHandler
public String exHandle(Exception ex, HttpServletRequest request){
if(ex instanceof ApplicationException){
//自定義的應用異常(賬號或密碼錯誤)
request.setAttribute("login_failed", ex.getMessage());//在登入頁面顯示錯誤原因
return "login";
}
//系統異常
return "error";
}
}
此處的ApplicationException,注意導包,是自己定義的異常(密碼或賬號錯誤所丟擲的異常),其餘的是RuntimeException(看做系統異常),在該類中分別處理異常,定位到不同的頁面,還可以記錄日誌等,此種處理異常的方式很靈活,建議使用