文章目錄
-
- 千人千面Elasticsearch實戰學習筆記
-
- 統一攔截異常處理
-
- 一、建構通用傳回類
- 二、錯誤傳回類
- 三、統一異常傳回
- 四、枚舉類錯誤定義
- 五、全局異常切面
- 六、@Valid 校驗傳入的參數
- 七、異常工具類
- 切面鑒權
-
- 一、注解定義切面
- 二、@Around() 環繞式
- Elasticsearch注意點
千人千面Elasticsearch實戰學習筆記
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-pXHzw7Fo-1624441203417)(千人千面Elasticsearch實戰學習筆記.assets/image-20210621142015949.png)]
搜尋和推薦是不同的
搜尋目标是明确的,推薦是根據搜尋習慣推送給使用者
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-2IP92Drt-1624441203421)(千人千面Elasticsearch實戰學習筆記.assets/image-20210621142752593.png)]
技術分解子產品分析
統一攔截異常處理
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-jmkZqE2u-1624441203424)(千人千面Elasticsearch實戰-學習筆記.assets/image-20210623150840735.png)]
一、建構通用傳回類
// 先定義一個通用傳回類,用來傳回成功和錯誤的data
// 成功就封裝資料,和success;失敗則提供errCode和errMsg
package com.imooc.dianping.common;
public class CommonRes {
//表明讀經請求的傳回處理結果,"success"或"fail"
private String status;
//若status=success時,表明對應的傳回的json類資料
//若status=fail時,則data内将使用通用的錯誤碼對應的格式
private Object data;
//定義一個通用的建立傳回對象的方法
public static CommonRes create(Object result){
return CommonRes.create(result,"success");
}
public static CommonRes create(Object result,String status){
CommonRes commonRes = new CommonRes();
commonRes.setStatus(status);
commonRes.setData(result);
return commonRes;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
二、錯誤傳回類
package com.imooc.dianping.common;
public class CommonError {
//錯誤碼
private Integer errCode;
//錯誤描述
private String errMsg;
public CommonError(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public CommonError(EmBusinessError emBusinessError){
this.errCode = emBusinessError.getErrCode();
this.errMsg = emBusinessError.getErrMsg();
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}
三、統一異常傳回
package com.imooc.dianping.common;
public class BusinessException extends Exception {
private CommonError commonError;
public BusinessException(EmBusinessError emBusinessError){
super();
this.commonError = new CommonError(emBusinessError);
}
public BusinessException(EmBusinessError emBusinessError,String errMsg){
super();
this.commonError = new CommonError(emBusinessError);
this.commonError.setErrMsg(errMsg);
}
public CommonError getCommonError() {
return commonError;
}
public void setCommonError(CommonError commonError) {
this.commonError = commonError;
}
}
四、枚舉類錯誤定義
package com.imooc.dianping.common;
public enum EmBusinessError {
//通用的錯誤類型10000開頭
NO_OBJECT_FOUND(10001,"請求對象不存在"),
UNKNOWN_ERROR(10002,"未知錯誤"),
NO_HANDLER_FOUND(10003,"找不到執行的路徑操作"),
BIND_EXCEPTION_ERROR(10004,"請求參數錯誤"),
PARAMETER_VALIDATION_ERROR(10005,"請求參數校驗失敗"),
//使用者服務相關的錯誤類型20000開頭
REGISTER_DUP_FAIL(20001,"使用者已存在"),
LOGIN_FAIL(20002,"手機号或密碼錯誤"),
//admin相關錯誤
ADMIN_SHOULD_LOGIN(30001,"管理者需要先登入"),
//品類相關錯誤
CATEGORY_NAME_DUPLICATED(40001,"品類名已存在"),
;
private Integer errCode;
private String errMsg;
EmBusinessError(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}
五、全局異常切面
package com.imooc.dianping.common;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 這個注解就是說,所有的Controller會被這個類檢測
@ControllerAdvice
public class GlobalExceptionHandler {
// 這個注解是,隻要有類傳回 Exception或繼承了,則會執行doError。比如【BusinessException】
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonRes doError(HttpServletRequest servletRequest, HttpServletResponse httpServletResponse,Exception ex){
if(ex instanceof BusinessException){
return CommonRes.create(((BusinessException)ex).getCommonError(),"fail");
}else if(ex instanceof NoHandlerFoundException){
CommonError commonError = new CommonError(EmBusinessError.NO_HANDLER_FOUND);
return CommonRes.create(commonError,"fail");
}else if(ex instanceof ServletRequestBindingException){
CommonError commonError = new CommonError(EmBusinessError.BIND_EXCEPTION_ERROR);
return CommonRes.create(commonError,"fail");
} else {
CommonError commonError = new CommonError(EmBusinessError.UNKNOWN_ERROR);
return CommonRes.create(commonError,"fail");
}
}
}
如果是404如何處理:加入兩個配置項
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-ToxOfwAJ-1624441203428)(千人千面Elasticsearch實戰-學習筆記.assets/image-20210623152739097.png)]
六、@Valid 校驗傳入的參數
最好是需要配合 BindingResult 做錯誤傳回
@RequestMapping("/register")
@ResponseBody
public CommonRes register(@Valid @RequestBody RegisterReq registerReq, BindingResult bindingResult)
throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
if(bindingResult.hasErrors()){
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,
CommonUtil.processErrorString(bindingResult));
}
UserModel registerUser = new UserModel();
registerUser.setTelphone(registerReq.getTelphone());
registerUser.setPassword(registerReq.getPassword());
registerUser.setNickName(registerReq.getNickName());
registerUser.setGender(registerReq.getGender());
UserModel resUserModel = userService.register(registerUser);
return CommonRes.create(resUserModel);
}
七、異常工具類
用來處理BindingResult傳回的報錯String,給前端提供更詳細的傳回
package com.imooc.dianping.common;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
public class CommonUtil {
public static String processErrorString(BindingResult bindingResult){
if(!bindingResult.hasErrors()){
return "";
}
StringBuilder stringBuilder = new StringBuilder();
for(FieldError fieldError:bindingResult.getFieldErrors()){
stringBuilder.append(fieldError.getDefaultMessage()+",");
}
return stringBuilder.substring(0,stringBuilder.length()-1);
}
}
效果:
@RequestMapping("/get")
@ResponseBody
public CommonRes getUser(@RequestParam(name="id")Integer id) throws BusinessException {
UserModel userModel = userService.getUser(id);
if(userModel == null){
//return CommonRes.create(new CommonError(EmBusinessError.NO_OBJECT_FOUND),"fail");
throw new BusinessException(EmBusinessError.NO_OBJECT_FOUND);
}else{
return CommonRes.create(userModel);
}
}
切面鑒權
沒有權限的直接跳轉到指定頁面,使用 Spring AOP做
課程4-6章
一、注解定義切面
package com.imooc.dianping.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AdminPermission {
String produceType() default "text/html";
}
調Controller前置校驗
二、@Around() 環繞式
進入就啟用,return調方法
package com.imooc.dianping.common;
import com.imooc.dianping.controller.admin.AdminController;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
@Aspect
@Configuration
public class ControllerAspect {
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private HttpServletResponse httpServletResponse;
@Around("execution(* com.imooc.dianping.controller.admin.*.*(..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object adminControllerBeforeValidation(ProceedingJoinPoint joinPoint) throws Throwable {
Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
AdminPermission adminPermission = method.getAnnotation(AdminPermission.class);
if(adminPermission == null){
//公共方法
Object resultObject = joinPoint.proceed();
return resultObject;
}
//判斷目前管理者是否登入,符合json傳回時的方法
String email = (String) httpServletRequest.getSession().getAttribute(AdminController.CURRENT_ADMIN_SESSION);
if(email == null){
if(adminPermission.produceType().equals("text/html")){
httpServletResponse.sendRedirect("/admin/admin/loginpage");
return null;
}else{
CommonError commonError= new CommonError(EmBusinessError.ADMIN_SHOULD_LOGIN);
return CommonRes.create(commonError,"fail");
}
}else{
Object resultObject = joinPoint.proceed();
return resultObject;
}
}
}
Elasticsearch注意點
Elasticsearch 作為非關系型資料庫
對于即使設定了mapping參數,但是如果新參數沒有産生沖突,還是會被記錄
