将RestTemplate封装为Util工具类

RestTemplate的封装已经很完善了,基本使用是不用处理的,直接用即可。但是实际使用中不仅仅是调用一下接口而已,可能还有其它的操作,比如最常见的记录请求和响应日志或者一些加密处理,这种随处可能存在的调用用AOP实现不是很友好,将其封装为Util是我认为比较合适的方法。

References:

关于RestTemplate的介绍和基本使用这里就不介绍了,相信看到这篇的都知道。
先看下RestTemplate注册为bean:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        // Do any additional configuration here
        return builder.build();
    }

}

然后就是将RestTemplate中常用的方法封装一遍,并添加上记录日志等处理操作。代码框架如下:

/**
 * Http工具类
 */
public class HttpUtil {
    private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);
    
    private RestTemplate restTemplate;
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doPostByJson(String url, Class<T> returnType) {
        return doPostByJson(url, null, returnType);
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T, E> T doPostByJson(String url, E data, Class<T> returnType) {
        return doPost(url, data, MediaType.APPLICATION_JSON_UTF8, returnType);
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doPostByFormData(String url, MultiValueMap<String, String> data, Class<T> returnType) {
        return doPost(url, data, MediaType.APPLICATION_FORM_URLENCODED, returnType);
    }
    
    /**
     * 发送GET请求
     * @param url 请求url
     * @param clazz 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doGet(String url, Class<T> clazz) {
        log.info("GET_REQUEST: {}, {}", url, clazz.getName());
        
//        T result = restTemplate.getForObject(url, clazz);
        log.info("GET_RESPONSE: {}", result);
        
        return result;
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param requestType 请求头类型
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T, E> T doPost(String url, E data, MediaType requestType, Class<T> returnType) {
        log.info("POST_REQUEST: {}, {}, {}, {}", url, data, requestType, returnType.getName());
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(requestType);
        HttpEntity<E> entity = new HttpEntity<>(data, headers);
        
//        T result = restTemplate.postForObject(url, entity, returnType);
        
        log.info("POST_RESPONSE: {}", result);
        return result;
    }
}

这里RestTemplate还没有初始化,我们需要注入之前注册的bean。但是问题来了,这个类是工具类,方法也应该都是static的,相应的,RestTemplate也应该是static的。知道我想说什么了吧,Spring不支持给静态变量注入,如果直接使用这个变量就是NullPointerException。这就比较尴尬了,不过难不住伟大的人民群众,参考mkyong的方法,为RestTemplate生成getter和setter方法,将Util注册为Component,然后在setter方法上注入即可,需要注意的是,用IDE给static变量生成的getter和setter也是static的,需要手动去除。完整代码如下:


/**
 * Http工具类
 */
@Component
public class HttpUtil {
    private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);
    
    private static RestTemplate restTemplate;
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doPostByJson(String url, Class<T> returnType) {
        return doPostByJson(url, null, returnType);
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T, E> T doPostByJson(String url, E data, Class<T> returnType) {
        return doPost(url, data, MediaType.APPLICATION_JSON_UTF8, returnType);
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doPostByFormData(String url, MultiValueMap<String, String> data, Class<T> returnType) {
        return doPost(url, data, MediaType.APPLICATION_FORM_URLENCODED, returnType);
    }
    
    /**
     * 发送GET请求
     * @param url 请求url
     * @param clazz 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T> T doGet(String url, Class<T> clazz) {
        log.info("GET_REQUEST: {}, {}", url, clazz.getName());
        
        T result = restTemplate.getForObject(url, clazz);
        log.info("GET_RESPONSE: {}", result);
        
        return result;
    }
    
    /**
     * 发送POST请求
     * @param url 请求url
     * @param data 发送的数据,必须重写toString()方法,否则不能正确记录日志信息
     * @param requestType 请求头类型
     * @param returnType 返回类型,必须重写toString()方法,否则不能正确记录日志信息
     * @return 指定的返回类型
     */
    public static final <T, E> T doPost(String url, E data, MediaType requestType, Class<T> returnType) {
        log.info("POST_REQUEST: {}, {}, {}, {}", url, data, requestType, returnType.getName());
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(requestType);
        HttpEntity<E> entity = new HttpEntity<>(data, headers);
        
        T result = restTemplate.postForObject(url, entity, returnType);
        
        log.info("POST_RESPONSE: {}", result);
        return result;
    }

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }
    
    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        HttpUtil.restTemplate = restTemplate;
    }
}

这样就可以通过Util使用RestTemplate了。

标签: none

仅有一条评论

  1. q q

    我都注册成组件了还能静态调用吗,构造器注入使用不行吗

添加新评论

ali-01.gifali-58.gifali-09.gifali-23.gifali-04.gifali-46.gifali-57.gifali-22.gifali-38.gifali-13.gifali-10.gifali-34.gifali-06.gifali-37.gifali-42.gifali-35.gifali-12.gifali-30.gifali-16.gifali-54.gifali-55.gifali-59.gif

加载中……