Spring RestTemplate 下载文件

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1、思考

面向服务编程中,我们经常需要通过HttpClient请求服务器获取对应的数据服务,如果你使用RestTemplate,肯定会在会他的 上传、下载,因为一般的Json数据请求都比较简单。下面就分享一下如何使用 RestTemplate 进行文件下载。

2、组件封装

package com.hnust.common.controller;

import com.hnust.common.rest.client.RestClient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.support.HttpRequestWrapper;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Heweipo on 2016/5/26.
 *
 * 资源下载通用控制器
 */
@RestController
public class DownloadController extends BaseController {


    /**
     * 发送/获取 服务端数据
     * 注意 URL 、HttpMethod 都与当前请求保持一致
     *
     * @return 返回结果(响应体)
     */
    protected ResponseEntity export() {
        return export(null, null);
    }

    /**
     * 主要是 GET、DELETE 请求不能发在body体
     *
     * @param uri 相对路径
     * @return 返回结果(响应体)
     */
    protected ResponseEntity export(String uri) {
        return export(uri, null);
    }

    /**
     * 添加参数
     *
     * @param params 请求body体
     * @return 返回结果(响应体)
     */
    protected ResponseEntity export(Map params) {
        return export(null, params);
    }

    /**
     * 下载通用方法
     *
     * @param params 请求参数
     * @return 下载流
     */
    protected ResponseEntity export(String uri, Map params) {
        // RestClient.getServiceServerUrl() 服务器的URL : http://localhost:8080/service
        String url = RestClient.getServiceServerUrl() + request.getRequestURI();
        if (!StringUtils.isEmpty(uri)) {
            url = RestClient.getServiceServerUrl() + uri;
        }

        HttpMethod httpMethod = getMethod();
        if(params == null) params = new HashMap<>();
        url = processParams(url,httpMethod,params);

        return export(url, httpMethod, params);
    }



    /**
     * 下载通用方法
     * @param url 地址
     * @param method 方法
     * @param params 参数
     * @return 下载流
     */
    protected ResponseEntity export(String url, HttpMethod method, Map params) {
        ClientHttpRequestInterceptor interceptor = new DownloadInterceptor();
        List list = new ArrayList<>();
        list.add(interceptor);

        restTemplate.setInterceptors(list);

        // 请求头
        HttpHeaders headers = new HttpHeaders();
        ObjectMapper mapper = new ObjectMapper();
        String str = null;
        try {
            if (params != null) {
                str = mapper.writeValueAsString(params);
            }
        } catch (JsonProcessingException e) { // 这个异常不处理
            e.printStackTrace();
        }

        // 发送请求
        HttpEntity entity = new HttpEntity<>(str, headers);
        ResponseEntity obj = restTemplate.exchange(url, method, entity, byte[].class);

        return obj;

    }


    /**
     * Spring RestTemplate 下载组件
     */
    public static class DownloadInterceptor implements ClientHttpRequestInterceptor{

        /**
          * 媒体类型,给个默认值
         */
        private MediaType headerValue = MediaType.ALL;

        /**
         * 获取媒体类型
         * @return 媒体类型
         */
        public MediaType getHeaderValue() {
            return headerValue;
        }

        /**
         * 设置媒体类型
         * @param headerValue 媒体类型
         */
        public void setHeaderValue(MediaType headerValue) {
            this.headerValue = headerValue;
        }


     /**
      * Intercept the given request, and return a response. The given {@link ClientHttpRequestExecution} allows
      * the interceptor to pass on the request and response to the next entity in the chain.
      * 

*

A typical implementation of this method would follow the following pattern: *

    *
  1. Examine the {@linkplain HttpRequest request} and body
  2. *
  3. Optionally {@linkplain HttpRequestWrapper wrap} the request to filter HTTP attributes.
  4. *
  5. Optionally modify the body of the request.
  6. *
  7. Either *
      *
    • execute the request using {@link ClientHttpRequestExecution#execute(HttpRequest, byte[])},
    • * or *
    • do not execute the request to block the execution altogether.
    • *
    *
  8. Optionally wrap the response to filter HTTP attributes.
  9. *
* * @param request the request, containing method, URI, and headers * @param body the body of the request * @param execution the request execution * @return the response * @throws IOException in case of I/O errors */ @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request); List list = new ArrayList<>(); list.add(headerValue); requestWrapper.getHeaders().setAccept(list); return execution.execute(requestWrapper, body); } } }

3、组件调用

package com.hnust.workbench.common.questionbank.paper.controller;

import com.hnust.common.controller.DownloadController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * 
 * Created by Heweipo on 2016/2/26.
 */
@RestController
public class ClientController extends DownloadController {

    /**
     * 下载
     * 
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public ResponseEntity getBatchAnswer(){
       return export();
    }
}

4、注意

1)RestTemplate 在这里只是做了一下转发,因为真正的文件是从另一个服务URL那里获取

2)RestTemplate 还有就是上传以及文本数据获取,项目中使用一般都会进行封装,方便调用

转载于:https://my.oschina.net/heweipo/blog/683233

你可能感兴趣的:(Spring RestTemplate 下载文件)