文章目录
千人千面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参数,但是如果新参数没有产生冲突,还是会被记录