springboot Service的路由

Spring_Boot專欄
上一篇 主目錄 下一篇

目錄

【前言】
在springboot項目中,使用GatewayController去統一處理渠道網管的請求服務,如何路由到具體的Service上呢?


GatewayController

@Slf4j
@RestController
public class GatewayController {

    @Autowired
    private ApiBaseService apiBaseService;
    @RequestMapping(value = "/auth/{version:.+}/{method:.+}", method = { RequestMethod.POST }, produces="application/json;charset=UTF-8" )
    public String baseController(@RequestBody JSONObject obj, @PathVariable String version, @PathVariable String method){
    	log.info("調用***服務請求參數打印, version={}, method={}", version, method);
        ApiReqBaseVo req =  JSON.toJavaObject(obj, ApiBaseVo.API_REQUEST_TYPE.get(version + method));
        req.setMethod(method);
        req.setVersion(version);
        ApiRespBaseVo resp = apiBaseService.handler(req);
        ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new CustomBeanSerializerModifier()));
		String json = "";
		try {
			 json = objectMapper.writeValueAsString(resp);
		} catch (Exception e) {
			log.error("數據異常轉換異常,userId={}, method={}, token={}, exception={}",req.getUid(), req.getMethod(), req.getToken(), e);
		}
        return json;
    }
}

ApiBaseService

@Slf4j
@Service
public class ApiBaseService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private Map<String, ApiAbstractService> apiServiceMap = new HashMap<>();
    @Autowired
    private List<ApiFilterChain> chains = new ArrayList<>();


    /**
     * service 路由方法
     * @param req
     * @return
     */
    public ApiRespBaseVo handler(ApiReqBaseVo req) {
        ApiRespBaseVo resp = null;
        try{
            doFilter(req);
            ApiAbstractService service = apiServiceMap.get(req.getMethod() + Constants.UNDERLINE + req.getVersion());
            if (validate(req) && service.validate(req)) {
                PrometheusMetricsInterceptor.localStatus.set(new Span("0000"));
                resp = service.invoke(req);
            }
            log.info("auth-service執行成功,入參={}",
                    JSONObject.toJSONString(req));
        }catch(ApiBusinessException e){
            log.error("auth-service執行異常,入參={}, exception={}",
                    JSONObject.toJSONString(req),e);
            throw e;
        }catch(Exception e){
            log.error("auth-service執行異常,入參={},exception={}",
                    JSONObject.toJSONString(req), e);
            ApiBusinessException ae = new ApiBusinessException(Constants.ApiCommon.API_RESP_CODE_1012, "服務器異常",req.getUid(), req.getMethod(), req.getToken());
            throw ae;
        }catch (Throwable e){
            log.error("auth-service執行異常,入參={},exception={}",
                    JSONObject.toJSONString(req), e);
            ApiBusinessException ae = new ApiBusinessException(Constants.ApiCommon.API_RESP_CODE_1012, "服務器異常",req.getUid(), req.getMethod(), req.getToken());
            throw ae;
        }
        return resp;
    }

    private void doFilter(ApiReqBaseVo req){
        for (ApiFilterChain apiFilterChain : chains) {
            ApiFilterChain chain = apiFilterChain;
            chain.filter(req);
        }
    }

ApiAbstractService service = apiServiceMap.get(req.getMethod() + Constants.UNDERLINE + req.getVersion()); 這一個是通過@Service(“XXX”)註解中的XXX獲得該Service類。例如:

ApiAbstractService

public abstract class ApiAbstractService{
}

Idcard2ServiceImpl

@Service(Constants.API_METHOD_IDCARD2 + Constants.UNDERLINE + Constants.ApiCommon.VERSION_1_0_0)
@Slf4j
public class Idcard2ServiceImpl extends ApiAbstractService {
}

通過apiServiceMap.get(Constants.API_METHOD_IDCARD2 + Constants.UNDERLINE + Constants.ApiCommon.VERSION_1_0_0)得到的是Idcard2ServiceImpl 類(ApiAbstractService 的子類)

這樣通過傳入的req得到method和version,就可以路由到相應的Service

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章