本文共 12341 字,大约阅读时间需要 41 分钟。
大概需要下面的三点:
实现SPI扩展点接口
package com.weibo.api.motan.filter;@Spipublic interface Filter { Response filter(Caller caller, Request request);}
业务代码实现Filter
public class PlsProviderExceptionFilter implements Filter { @Override public Response filter(Caller caller, Request request) { //实现具体的业务逻辑 }}
实现类增加注解
@Spi(scope = Scope.SINGLETON) //扩展加载形式,单例或多例@SpiMeta(name = "motan") //name表示扩展点的名称,根据name加载对应扩展@Activation(sequence = 100) //同类型扩展生效顺序,部分扩展点支持。非必填
@SpiMeta(name = "pls-exception-filter")//sequence默认20,越大越先执行完@Activation(sequence = 100, key = { MotanConstants.NODE_TYPE_SERVICE})public class PlsProviderExceptionFilter implements Filter { //...}
增加SPI实现声明 c l a s s p a t h / M E T A − I N F / s e r v i c e s / {classpath}/META-INF/services/ classpath/META−INF/services/{SPI interface fullname}文件中添加对应SPI接口实现类全名。 可参照motan-core模块/META-INF/services/下的配置
#扩展接口com.sxl.motan.PlsProviderExceptionFilter
官方对moten扩展机制介绍
filter机制是在client端与server端请求处理是都会经过的过滤机制,使用者可以通过filter来实现对请求的request和response进行定制化处理。 filter扩展的实现方式是通过上述的SPI扩展,使用中有如下问题需要注意。
1、如何使扩展的filter生效。
SPI扩展必须对应一个唯一的name,实际使用中通过name来加载扩展。一般扩展需要在配置中设置对应的name,然后自动加载。
filter扩展默认是不生效的,加载filter的方式分为强制加载和指定加载。如果需要强制生效,可以通过配置@Activation来实现,MotanConstants.NODE_TYPE_SERVICE表示在server端强制生效,MotanConstants.NODE_TYPE_REFERER表示在client端强制生效。 强制生效情况下,不管任何service都会进行filter过滤。 配置样例如下:
@Activation(key = { MotanConstants.NODE_TYPE_SERVICE, MotanConstants.NODE_TYPE_REFERER })
如果只需要在某些service中生效,则可以直接通过在basicService或者service中配置 filter="filter_name"即可,其中的filter_name就是扩展filter中声明的@SpiMeta(name = “***”)中name的值
推荐通过配置方式使用filter,减少不必要的filter装载
用于规范异常,各个模块维护自己的异常编码。对应的异常编码可以同步 [帮助系统并给出解决方案。方便***用户查找解决***
package com.sxl.exception.errorCode;/** * 系统各平台业务异常枚举 * @ClassName: com.sxl.exception.PlsBizErrorCode.java * @author: songxulin * @date : 2021-01-04 15:37 * @version V1.0 */public enum PlsBizErrorCode { /************************** 公共异常 *****************************/ E_000000("000000","fail","失败"),E_000001("000001","success","成功"),E_000002("000002","parameterError","请求参数为空"), E_000003("000003","parameterInvalid","请求参数非法"),E_000004("000004","jsonError","JSON转换失败"),E_000005("000005","dbError","数据库异常"), E_000006("000006","networkError","网络异常"),E_000007("000007","unkownError","未知异常"),E_000008("000008","handleDataException","数据处理异常"), E_000009("000009","existed","数据已存在"), E_000010("000010","numberFormatException","数值转换异常"),E_000011("000011","NullPointerException","数据空指针异常"), /************************** 通用模块异常 ******************************/ P_C00001("P_C00001","skuParseError","sku解析异常"), ; private String code; private String name; private String desc; PlsBizErrorCode(String code, String name, String desc) { this.code = code; this.name = name; this.desc = desc; } @Override public String getCode() { return code; } @Override public String getName() { return name; } @Override public String getDesc() { return desc; }}
异常统一继承此类
package com.sxl.exception;import com.sxl.exception.errorCode.ErrorCode;/** * 刊登系统异常抽象类 * @ClassName: com.sxl.exception.AbstractException.java * @author: songxulin * @date : 2021-01-04 17:27 * @version V1.0 */public abstract class AbstractPLSException extends RuntimeException{ private static final long serialVersionUID = -4470524790791804455L; private String state; private String name; private void init(String code, String name){ this.state = code; this.name = name; } private void init(ErrorCode errorCode){ init(errorCode.getCode(), errorCode.getName()); } private AbstractPLSException(String message) { super(message); } private AbstractPLSException(String message, Throwable cause){ super(message,cause); } public AbstractPLSException(String code, String name, String desc){ this(desc); init(code, name); } public AbstractPLSException(String code, String name, String desc, Throwable cause{ this(desc, cause); init(code, name); } public AbstractPLSException(ErrorCode errorCode){ this(errorCode.getDesc()); init(errorCode); } public AbstractPLSException(ErrorCode errorCode, String desc){ this(desc); init(errorCode); } public AbstractPLSException(ErrorCode errorCode, Throwable cause){ this(errorCode.getDesc(), cause); init(errorCode); } public String getState() { return state; } public String getName() { return name; } public String getStateMsg(){ return state+":"+getMessage(); }}
package com.sxl.exception;import com.sxl.exception.errorCode.ErrorCode;/** * 刊登系统业务异常 * @ClassName: com.sxl.exception.PlsBizException.java * @author: songxulin * @date : 2021-01-04 15:36 * @version V1.0 */public class PlsBizException extends AbstractPLSException { private static final long serialVersionUID = 5600133107550376666L; public PlsBizException(String code, String name, String desc) { super(code, name, desc); } public PlsBizException(ErrorCode errorCode, String desc) { super(errorCode,desc); } public PlsBizException(ErrorCode errorCode) { super(errorCode); } public PlsBizException(ErrorCode errorCode, Throwable cause) { super(errorCode, cause); }}
package com.sxl.exception;import com.alibaba.fastjson.JSONException;import com.sxl.exception.errorCode.ErrorCode;import com.sxl.exception.errorCode.PlsBizErrorCode;import java.util.HashMap;import java.util.Map;/** * 异常枚举 * @ClassName: com.sxl.exception.ExceptionEnum.java * @author: songxulin * @date : 2021-01-04 19:38 * @version V1.0 */public enum ExceptionEnum { JSONException("JSONException", JSONException.class, PlsBizErrorCode.E_000004), NumberFormatException("NumberFormatException",NumberFormatException.class, PlsBizErrorCode.E_000010), NullPointerException("NullPointerException",NullPointerException.class, PlsBizErrorCode.E_000010), IllegalArgumentException("IllegalArgumentException",IllegalArgumentException.class,PlsBizErrorCode.E_000008), ; private String name; private Class clazz; private ErrorCode errorCode; private static MapenumMap =new HashMap<>(16); static { for (ExceptionEnum value : ExceptionEnum.values()) { enumMap.put(value.clazz,value); } } ExceptionEnum(String name, Class clazz, ErrorCode errorCode) { this.name = name; this.clazz = clazz; this.errorCode = errorCode; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } public ErrorCode getErrorCode() { return errorCode; } public void setErrorCode(ErrorCode errorCode) { this.errorCode = errorCode; } /** * 根据异常类获取对应异常 * @param e Class 异常class * @return ExceptionEnum */ public static ExceptionEnum getByClazz(Class e){ return enumMap.get(e); }}
package com.sxl.motan;import com.alibaba.fastjson.JSON;import com.weibo.api.motan.common.MotanConstants;import com.weibo.api.motan.core.extension.Activation;import com.weibo.api.motan.core.extension.SpiMeta;import com.weibo.api.motan.exception.MotanAbstractException;import com.weibo.api.motan.filter.Filter;import com.weibo.api.motan.rpc.Caller;import com.weibo.api.motan.rpc.DefaultResponse;import com.weibo.api.motan.rpc.Request;import com.weibo.api.motan.rpc.Response;import com.sxl.exception.AbstractPLSException;import com.sxl.exception.ExceptionEnum;import com.sxl.exception.PLSServiceException;import com.sxl.vo.ResultVO;import com.sxl.vo.VoHelper;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * * @ClassName: com.sxl.motan.PlsProviderExceptionFilter.java * @author: songxulin * @date : 2021-01-04 20:09 * @version V1.0 */@SpiMeta(name = "pls-exception-filter")//sequence默认20,越大越先执行完@Activation(sequence = 100, key = { MotanConstants.NODE_TYPE_SERVICE})public class PlsProviderExceptionFilter implements Filter { private final static Logger log = LoggerFactory.getLogger(PlsProviderExceptionFilter.class); @Override public Response filter(Caller caller, Request request) { Response response; try { response = caller.call(request); } catch (Exception e) { log.error(e.getMessage(), e); return buildExceptionResponse(e); } if (response.getException() != null) { log.error(String.format("%s,%s 调用异常",request.getAttachments().get("host"),request.getMethodName()),response.getException().getCause()); return buildExceptionResponse(response); } return response; } /** * 构建异常Response * @param e 异常 * @return Response */ private Response buildExceptionResponse(Exception e) { DefaultResponse response = new DefaultResponse(); AbstractPLSException ex; //自定义异常 if (e instanceof MotanAbstractException) { ex = getException((MotanAbstractException) e); } else { //系统未知异常 ex = new PLSServiceException("", "", "系统未知异常"); } response.setValue(JSON.toJSONString(formatError(ex))); return response; } /** * 获取异常类型 * @param e 异常 * @return AbstractPLSException */ private AbstractPLSException getException(MotanAbstractException e) { Throwable cause = e.getCause(); if (cause instanceof AbstractPLSException) { return (AbstractPLSException) cause; } else { ExceptionEnum exceptionEnum = ExceptionEnum.getByClazz(cause.getClass()); if(exceptionEnum!=null){ return new PLSServiceException(exceptionEnum.getErrorCode()); } return new PLSServiceException("", "", "系统未知异常"); } } /** * 格式化异常 * @param e AbstractPLSException * @return ResultVO 自定义返回体 */ private ResultVO formatError(AbstractPLSException e) { return VoHelper.getErrorResult(e.getStateMsg()); } private Response buildExceptionResponse(Response response) { return buildExceptionResponse(response.getException()); }}
完成上面的代码后,motan接口统一处理就完成了。
throw new PlsBizException(PlsBizErrorCode.P_YA0001);
异常不进行抓取 ,需要处理异常的地方进行抛出 throws Exception
没有统一处理前
@Overridepublic String addListing(String jsonParam) { LOGGER.info("新增listing接口被请求,请求参数jsonParam:{}", jsonParam); ResultVO resultVO = new ResultVO(); try { //... resultVO = iPlsAliexpressListingService.addListing(data, operator); } catch (ValidatorParameterException vpe) { resultVO.setMsg(vpe.getMessage()); resultVO.setState(ResponseCode.FAIL.getCode()); } catch (WarningException e) { resultVO.setMsg(e.getMessage()); resultVO.setState(ResponseCode.WARNING.getCode()); LOGGER.error("AliExpress addListing 新增Listing 侵权检测警告,{} ", e.getMessage(), e); } catch (Exception e) { resultVO.setMsg(e.getMessage()); resultVO.setState(ResponseCode.FAIL.getCode()); LOGGER.error("新增listing接口异常", e); } return JSONUtils.toJSON(resultVO);}
统一处理后
@Override public String addListing(String jsonParam) throws Exception{ LOGGER.info("新增listing接口被请求,请求参数jsonParam:{}", jsonParam); //.. ResultVO resultVO = iPlsAliexpressListingService.addListing(data, operator); }
可以看到代码变得简洁了很多,而且异常的格式也得到规范。
} catch (Exception e) { resultVO.setMsg(e.getMessage()); resultVO.setState(ResponseCode.FAIL.getCode()); LOGGER.error("新增listing接口异常", e);}return JSONUtils.toJSON(resultVO);
}
统一处理后```java @Override public String addListing(String jsonParam) throws Exception{ LOGGER.info("新增listing接口被请求,请求参数jsonParam:{}", jsonParam); //.. ResultVO resultVO = iPlsAliexpressListingService.addListing(data, operator); }
可以看到代码变得简洁了很多,而且异常的格式也得到规范。
转载地址:http://qzmlf.baihongyu.com/