123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package com.cpic.home.governor.service.impl;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Method;
- import java.lang.reflect.Parameter;
- import java.lang.reflect.Type;
- import java.util.HashMap;
- import java.util.Map;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.ContentType;
- import org.apache.http.entity.mime.MultipartEntityBuilder;
- import org.apache.http.entity.mime.content.FileBody;
- import org.apache.http.entity.mime.content.InputStreamBody;
- import org.apache.http.entity.mime.content.StringBody;
- import org.apache.http.impl.client.HttpClientBuilder;
- import org.apache.http.util.EntityUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.aop.framework.ProxyFactory;
- import org.springframework.beans.factory.FactoryBean;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
- import org.springframework.web.multipart.MultipartFile;
- import com.alibaba.fastjson.JSON;
- import com.cpic.caf.compon.tech.utils.CharsetUtil;
- import com.cpic.home.governor.service.JobSchedulerService;
- import feign.Feign;
- import feign.Param;
- import feign.RequestLine;
- import feign.RequestTemplate;
- import feign.Response;
- import feign.Util;
- import feign.codec.Decoder;
- import feign.codec.Encoder;
- import feign.gson.GsonDecoder;
- /**
- * 该类为 JobSchedulerService 实例,因需要调用 JobScheduler, 需远程执行接口。
- *
- *
- * <pre>
- *
- * Created by zhenqin.
- * User: zhenqin
- * Date: 2019/3/26
- * Time: 18:43
- * Vendor: primeton.com
- * To change this template use File | Settings | File Templates.
- *
- * </pre>
- *
- * @author zhenqin
- */
- @Component("jobSchedulerService")
- public class JobSchedulerServiceImpl implements InitializingBean, FactoryBean<JobSchedulerService>,
- MethodInterceptor {
- /**
- * JobScheduler 地址
- */
- @Value("${jobscheduler.url}")
- String jobSchedulerUrl;
- private HttpClient httpclient = null;
- static Logger logger = LoggerFactory.getLogger(JobSchedulerServiceImpl.class);
- @Override
- public void afterPropertiesSet() throws Exception {
- HttpClient httpclient = HttpClientBuilder.create().build();
- this.httpclient = httpclient;
- }
- @Override
- public JobSchedulerService getObject() throws Exception {
- JobSchedulerService jobSchedulerService = Feign.builder()
- .encoder(feignEncoder())
- .decoder(feignDecoder())
- .target(JobSchedulerService.class, jobSchedulerUrl);
- // AOP,拦截上传文件的接口
- ProxyFactory proxyFactory = new ProxyFactory();
- proxyFactory.addAdvice(this);
- proxyFactory.setTarget(jobSchedulerService);
- // 获得代理类
- return (JobSchedulerService) proxyFactory.getProxy();
- }
- @Override
- public Class<?> getObjectType() {
- return JobSchedulerService.class;
- }
- /**
- * AOP 织入
- *
- * @param invocation
- * @return
- * @throws Throwable
- */
- @Override
- public Object invoke(MethodInvocation invocation) throws Throwable {
- Object[] arguments = invocation.getArguments();
- boolean isMutilForm = false;
- for (Object argument : arguments) {
- // 文件
- isMutilForm = argument instanceof File || argument instanceof MultipartFile;
- if (isMutilForm) {
- // 有一个是文件的,则是上传
- break;
- }
- }
- Object result = null;
- if (!isMutilForm) {
- // 普通表单
- result = invocation.proceed();
- } else {
- // 文件上传
- result = new HashMap<>();
- Method method = invocation.getMethod();
- RequestLine requestLine = method.getAnnotation(RequestLine.class);
- if (requestLine != null) {
- String[] split = requestLine.value().split("\\s+");
- String url = jobSchedulerUrl + split[1];
- Map<String, Object> form = new HashMap<>();
- Parameter[] parameters = method.getParameters();
- Annotation[][] annotations = method.getParameterAnnotations();
- int i = 0;
- for (Parameter parameter : parameters) {
- form.put(getFormName(parameter, annotations[i]), invocation.getArguments()[i]);
- i++;
- }
- // 提交表单
- return executeRest(url, form);
- }
- }
- return result;
- }
- /**
- * 提交表单
- *
- * @param form 提交表单,携带文件
- * @return
- */
- public Map<String, Object> executeRest(String url, Map<String, Object> form) {
- HttpPost request = new HttpPost(url);
- MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
- InputStream in = null;
- try {
- for (Map.Entry<String, Object> entry : form.entrySet()) {
- if (entry.getValue() instanceof File || entry.getValue() instanceof MultipartFile) {
- if (entry.getValue() instanceof File) {
- String name = ((File) entry.getValue()).getName();
- multipartEntityBuilder.addPart(entry.getKey(), new FileBody((File) entry.getValue()));
- multipartEntityBuilder.addPart("name", new StringBody(name, ContentType.MULTIPART_FORM_DATA));
- } else {
- MultipartFile uploadFile = (MultipartFile) entry.getValue();
- in = uploadFile.getInputStream();
- String name = ((MultipartFile) entry.getValue()).getOriginalFilename();
- multipartEntityBuilder.addPart(entry.getKey(), new InputStreamBody(in, ContentType.MULTIPART_FORM_DATA, name));
- multipartEntityBuilder.addPart("name", new StringBody(name, ContentType.MULTIPART_FORM_DATA));
- }
- } else {
- multipartEntityBuilder.addPart(entry.getKey(),
- (entry.getValue() instanceof String ? new StringBody((String) entry.getValue(), ContentType.MULTIPART_FORM_DATA) :
- new StringBody(String.valueOf(entry.getValue()), ContentType.MULTIPART_FORM_DATA)));
- }
- }
- request.setEntity(multipartEntityBuilder.build());
- HttpResponse response = httpclient.execute(request);
- if (response.getStatusLine().getStatusCode() == 200) {
- String json = EntityUtils.toString(response.getEntity(), CharsetUtil.CHARSET_UTF_8);
- logger.info(json);
- return JSON.parseObject(json);
- } else {
- logger.error("execute {} error.", request.getURI());
- }
- } catch (IOException e) {
- logger.error("execute rest api error.", e);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- }
- }
- }
- return new HashMap<>();
- }
- /**
- * 获取该 参数的名称,@Param 注解名称,若没有选择字段名称
- *
- * @param parameter
- * @param param
- * @return
- */
- String getFormName(Parameter parameter, Annotation[] param) {
- if (param == null || param.length == 0) {
- return parameter.getName();
- }
- // 选择 param 的名称
- Param params = (Param) param[0];
- return params.value();
- }
- public void setJobSchedulerUrl(String jobSchedulerUrl) {
- this.jobSchedulerUrl = jobSchedulerUrl;
- }
- public static Decoder feignDecoder() {
- // JSON
- GsonDecoder gsonDecoder = new GsonDecoder();
- return (Response response, Type type) -> {
- Response.Body body = response.body();
- if (body == null) {
- return null;
- }
- if (String.class.equals(type)) {
- return Util.toString(body.asReader());
- }
- return gsonDecoder.decode(response, type);
- };
- }
- public static Encoder feignEncoder() {
- // JSON
- return (Object object, Type bodyType, RequestTemplate template) -> {
- if (bodyType == String.class) {
- template.body((String)object);
- } else if (bodyType == byte[].class) {
- template.body((byte[]) object, CharsetUtil.CHARSET_UTF_8);
- } else if (object instanceof Number) {
- template.body(String.valueOf(object));
- }
- template.body(JSON.toJSONString(object));
- };
- }
- }
|