封裝一份ribbon請求的客戶端代碼

沒有前戲,直接上代碼。

註冊中心:

使用 eureka

客戶端:

1、配置文件

spring.application.name=my-user
server.port=8084

eureka.client.serviceUrl.defaultZone=http://admin:admin@localhost:8763/eureka/

three.server.order.name=my-order

2、Controller

@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    //封裝調用第三方服務類
    @Autowired
    private OrderThreeService orderThreeService;

    @RequestMapping("/get")
    public String getOrder(String key){
        // get方法調用服務端接口
        String result = orderThreeService.getOrder(key,1);
        log.info(result);

        //post 方法調用服務端接口
        OrderModel orderModel = new OrderModel();
        orderModel.setId(1L);
        orderModel.setName("1號訂單");
        result = orderThreeService.save(orderModel);
        log.info(result);

        return result;
    }
}

3、封裝類  OrderThreeService 、實現類 OrderThreeServiceImpl

public interface OrderThreeService {
    String getOrder(String key,Integer valid);
    String save(OrderModel orderModel);
}

@Component
public class OrderThreeServiceImpl extends AbstractThreeService implements OrderThreeService {

    @Value("${three.server.order.name}")
    private String serverName;

    @Autowired
    private RestTemplate restTemplate;

    @HandlerMethodUrlParameter("order/get?key=&valid=")
    @Override
    public String getOrder(String key,Integer valid){
        String url = buildUrlHttp(serverName, "getOrder", key,valid.toString());
        String result = restTemplate.getForObject(url, String.class);
        return result;
    } 

    @HandlerMethodUrlParameter("order/save")
    @Override
    public String save(OrderModel orderModel){
        String url = buildUrlHttp(serverName, "save", null);
        ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, orderModel, String.class);
        return stringResponseEntity.getBody();
    }
}

注: 

String url = buildUrlHttp(serverName, "getOrder", key,valid.toString()); 第一個參數爲服務名,第二個爲方法名,寫在哪個方法就寫那個方法的名字,後續就爲參數名稱了,有幾個就寫幾個,和方法上註解@HandlerMethodUrlParameter("order/get?key=&valid=") 的=數量匹配。

4、第三方服務抽象基類 AbstractThreeService

其他服務的接口類,只要繼承 AbstractThreeService 就可以按 OrderThreeServiceImpl 的方式實現


public abstract class AbstractThreeService {

    private Map<String,String> methodParameter = new HashMap<>();

    @PostConstruct
    public void init(){
        ReflectionUtils.doWithMethods(this.getClass(), method -> {
            HandlerMethodUrlParameter hmup = method.getAnnotation(HandlerMethodUrlParameter.class);
            if(hmup != null){
                methodParameter.put(method.getName(),hmup.value());
            }
        });
    }

    protected String buildUrlHttp(String serverName,String method,String... args) {
        return String.format("%s/%s",buildUrlHttp(serverName),buildGetParam(methodParameter.get(method),args));
    }

    protected String buildUrlHttp(String serverName) {
        return String.format("http://%s", serverName);
    }

    protected String buildUrlHttps(String serverName,String method,String... args) {
        return String.format("%s/%s",buildUrlHttps(serverName),buildGetParam(methodParameter.get(method),args));
    }
    protected String buildUrlHttps(String serverName) {
        return String.format("https://%s", serverName);
    }

    /**
     * TODO pattern格式爲 key1=&key2=
     * @param pattern
     * @param agrs
     * @return
     */
    protected String buildGetParam(String pattern,String... agrs) {
        if(StringUtils.isBlank(pattern) || agrs ==null || agrs.length == 0){
            return pattern;
        }

        pattern = pattern.replace("=","=%s");
        return String.format(pattern, agrs);
    }
}

5、標識每個方法調用對應接口的地址輔助註解

注 :@HandlerMethodUrlParameter("order/get?key=&valid=") 參數的封裝格式   key=&valid= 

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HandlerMethodUrlParameter {
    String value() default "";
}

 

服務端

1、提供的接口方法

@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/get")
    public String getOrder(String key,Integer valid){
        String result = "getOrder --> key=" + key +"&valid="+valid;
        log.info(result);
        return result;
    }
 
    @PostMapping("/save")
    public String save(@RequestBody OrderModel orderModel){
        String result = "save --> key=" + JSONObject.toJSONString(orderModel);
        log.info(result);
        return result;
    }
}

 

測試:

瀏覽器上調用 客戶端的接口,客戶端接口會去調用服務端接口方法,且返回信息到客戶端

 

 

 

 

 

 

 

 

 

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