SpringCloud 通用模块(common 服务)
2019-09-26 本文已影响0人
qyfl
common 服务是做什么的
- 将通用的配置,代码从各个业务模块中抽取出来,在 common 里实现一份。
- 将响应的格式统一起来。
- 将异常等信息,日志等格式也统一起来,在 common 里实现。
这么做的好处是什么
- 公共的模块维护方便,更新方便。
- 返回给客户端的响应,格式统一,客户端开发方便,与客户端对接方便。
- 将异常、日志等格式统一起来,查找 bug 方便,排错快。
怎么做
怎么在 IDE 里,新建模块,修改依赖这些内容。太基础,就不提了。
通用响应模块
通用响应模块主要分两部分,第一步要定义好响应的格式。第二步,要拦截所有的或指定的响应。然后包装成定要好的格式
响应格式,每个公司可能都有自己的规范,简单的示例如下:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResponse<T> implements Serializable {
private Integer code;
private String message;
private T data;
public CommonResponse(Integer code, String message) {
this.code = code;
this.message = message;
}
}
拦截包装响应。拦截什么不拦截什么,怎么包装都是根据业务不同,实现不同的。简单的示例如下:
import com.imooc.ad.annotation.IgnoreResponseAdvice;
import com.imooc.ad.vo.CommonResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {
/**
* 对那些响应进行忽略,以下是使用了特定注解的方法和类忽略。
* @param methodParameter
* @param aClass
* @return
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
return false;
}
if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
return false;
}
return true;
}
/**
* beforeBodyWrite 的意思就是在写入之前做的事。在这个方法里修改格式。
* @param o
* @param methodParameter
* @param mediaType
* @param aClass
* @param serverHttpRequest
* @param serverHttpResponse
* @return
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
CommonResponse<Object> response = new CommonResponse<>(0, "");
if (null == o) {
return response;
} else if (o instanceof CommonResponse) {
response = (CommonResponse<Object>) o;
} else {
response.setData(o);
}
return response;
}
}
以下是忽略拦截注解的实现
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreResponseAdvice {
}
统一的异常模块
异常处理,严格来说也是属于响应。
自定义的异常类,具体业务忽略,简单示例如下:
public class AdException extends Exception {
public AdException(String message) {
super(message);
}
}
捕获异常处理,简单示例如下:
import com.imooc.ad.exception.AdException;
import com.imooc.ad.vo.CommonResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
@RestControllerAdvice
public class GlobalExceptionAdvice {
/**
* @ExceptionHandler 注解的意思是只捕获指定异常类。如果我们抛出的是 AdException 则会被捕获。
* @param req
* @param ex
* @return
*/
@ExceptionHandler(value = AdException.class)
public CommonResponse<String> handlerAdException(HttpServletRequest req, AdException ex) {
CommonResponse<String> response = new CommonResponse<>(-1, "busniess error");
response.setData(ex.getMessage());
return response;
}
}