File文件转发
2019, Feb 09
File文件转发
项目中,采用的是基于Spring Cloud微服务架构,消费者需要转发请求参数到生产者,但是,要转发的文件是MutipartFile类型。
MutipartFile是spring里面定义的接口,封装了用户在上传图片时所包含的所有信息。直接用restTemplate转发会抛异常。
有两个解决思路:1.把MutipartFile写到本地,然后restTemplate上传。2.不用restTemplate,用HttpClient发送字节数组(生产者仍然可以用file接收),省去写文件和读文件的开销
出于性能考虑,选择后者。
1.HttpClien模拟表单转发请求参数
@RequestMapping(value = "addContactByExcel", method = RequestMethod.POST)
public String addContactByExcel(@RequestParam("userId") String userId,
@RequestParam("groupName") String groupName,
@RequestParam("excel") MultipartFile excel) {
try {
String url = ServiceDiscover.loadBlance("department-service") + "/addressList/addContactByExcel";
// 自定义ContentType,用来传输中文
ContentType CHINESE_CONTENT_TYPE = ContentType.create("text/plain", Consts.UTF_8);
// 模拟发送psot表单
HttpPost post = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("excel", excel.getBytes(), ContentType.MULTIPART_FORM_DATA, "excel.xls");
builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN);
builder.addTextBody("groupName", groupName, CHINESE_CONTENT_TYPE);
org.apache.http.HttpEntity entity = builder.build();
post.setEntity(entity);
CloseableHttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(post);
return IOUtils.toString(response.getEntity().getContent(), "utf-8");
} catch (Exception e) {
return e.getMessage();
}
}
2.自定义服务发现
package cn.bookcycle.consumer.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* ServiceDiscover
*
* @author Flynn
* @version 1.0
* @description 手动服务发现
* @email liufenglin@163.com
* @date 2019/2/8
*/
@Component
public class ServiceDiscover {
private static DiscoveryClient discoveryClient;
@Autowired
public void setDiscoveryClient(DiscoveryClient discoveryClient) {
ServiceDiscover.discoveryClient = discoveryClient;
}
/**
* 对指定服务进行负载均衡选择
*
* @param serviceName 服务名
* @return 生产者的地址
* @throws Exception 没有服务的生产者异常
*/
public static String loadBlance(String serviceName) throws Exception {
List hosts = hosts(serviceName);
if (hosts.size() == 0) {
throw new Exception("no service producer");
}
int size = hosts.size();
return hosts.get(new Random().nextInt(size)).toString();
}
/**
* 获取服务的所有IP地址
*
* @param serviceName 服务名
* @return 服务的所有IP地址构成的List,List的size可以为0
*/
private static List hosts(String serviceName) {
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
List hosts = new ArrayList();
serviceInstances.forEach(serviceInstance -> {
hosts.add(serviceInstance.getUri());
});
return hosts;
}
}