xusonglin il y a 5 ans
Parent
commit
ce26f0604a

+ 96 - 0
pom.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.4.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.jkcredit</groupId>
+    <artifactId>car-credit</artifactId>
+    <version>3.0</version>
+    <name>car-credit</name>
+    <description>Demo project for Spring Boot</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.58</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.9</version>
+        </dependency>
+<!--        &lt;!&ndash;web 模块&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-web</artifactId>-->
+<!--            <exclusions>-->
+<!--                &lt;!&ndash;排除tomcat依赖&ndash;&gt;-->
+<!--                <exclusion>-->
+<!--                    <artifactId>spring-boot-starter-tomcat</artifactId>-->
+<!--                    <groupId>org.springframework.boot</groupId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash;undertow容器&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-undertow</artifactId>-->
+<!--        </dependency>-->
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories><!-- 代码库 -->
+        <repository>
+            <id>maven-ali</id>
+            <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+                <updatePolicy>always</updatePolicy>
+                <checksumPolicy>fail</checksumPolicy>
+            </snapshots>
+        </repository>
+    </repositories>
+</project>

+ 16 - 0
src/main/java/com/jkcredit/CarCreditApplication.java

@@ -0,0 +1,16 @@
+package com.jkcredit;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CarCreditApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CarCreditApplication.class, args);
+    }
+
+
+
+
+}

+ 24 - 0
src/main/java/com/jkcredit/config/BaseResult.java

@@ -0,0 +1,24 @@
+package com.jkcredit.config;
+
+import lombok.Data;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-14 12:00
+ * @version: V1.0
+ **/
+@Data
+public class BaseResult<T> {
+
+    private Integer code;
+
+//    private Integer status;
+
+    private String msg;
+
+    private T data;
+
+    private String transactionId;
+
+}

+ 52 - 0
src/main/java/com/jkcredit/config/RestTemplateConfig.java

@@ -0,0 +1,52 @@
+package com.jkcredit.config;
+
+import com.jkcredit.utils.HttpClientUtils;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @description: RestTemplate配置类
+ * @author: sunzhaoning
+ * @create: 2019-05-14 11:21
+ * @version: V1.0
+ **/
+@Configuration
+public class RestTemplateConfig {
+
+    @Bean
+    public RestTemplate httpsRestTemplate(HttpComponentsClientHttpRequestFactory httpsFactory) {
+        httpsFactory.setConnectTimeout(1000);
+        httpsFactory.setReadTimeout(5000);
+        RestTemplate restTemplate = new RestTemplate(httpsFactory);
+        restTemplate.setErrorHandler(
+                new ResponseErrorHandler() {
+                    @Override
+                    public boolean hasError(ClientHttpResponse clientHttpResponse) {
+                        return false;
+                    }
+
+                    @Override
+                    public void handleError(ClientHttpResponse clientHttpResponse) {
+                        // 默认处理非200的返回,会抛异常
+                    }
+                });
+        return restTemplate;
+    }
+
+    @Bean(name = "httpsFactory")
+    public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory()
+            throws Exception {
+        CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
+        HttpComponentsClientHttpRequestFactory httpsFactory =
+                new HttpComponentsClientHttpRequestFactory(httpClient);
+        httpsFactory.setReadTimeout(400);
+        httpsFactory.setConnectTimeout(400);
+        return httpsFactory;
+    }
+
+}

+ 31 - 0
src/main/java/com/jkcredit/controller/CarInfoController.java

@@ -0,0 +1,31 @@
+package com.jkcredit.controller;
+
+import com.jkcredit.config.BaseResult;
+import com.jkcredit.service.CarService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-14 11:08
+ * @version: V1.0
+ **/
+@Slf4j
+@RestController
+@RequestMapping("/api")
+public class CarInfoController {
+
+    @Autowired
+    private CarService carService;
+
+    @PostMapping("/v1")
+    public BaseResult<String> doPost(@RequestBody Map<String, String> params) throws UnsupportedEncodingException {
+        return carService.car(params);
+    }
+
+}

+ 49 - 0
src/main/java/com/jkcredit/entity/Car.java

@@ -0,0 +1,49 @@
+package com.jkcredit.entity;
+
+import lombok.Data;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-14 11:38
+ * @version: V1.0
+ **/
+@Data
+public class Car {
+    /**
+     * 发动机号
+     */
+    private String engineNumber="";
+    /**
+     * 车辆识别代号
+     */
+    private String vehicleIdentificationNumber="";
+    /**
+     * 车架号
+     */
+    private String vin="";
+    /**
+     * 号牌号码
+     */
+    private String plateNumber="";
+    /**
+     * 号牌种类
+     */
+    private String plateType;
+    /**
+     *初次登记日期
+     */
+    private String registrationDate;
+    /**
+     *车辆品牌
+     */
+    private String vehicleBrand;
+    /**
+     *发证机关
+     */
+    private String certificationAuthority;
+    /**
+     *抵押标记
+     */
+    private String isMortgage;
+}

+ 40 - 0
src/main/java/com/jkcredit/exception/BaseException.java

@@ -0,0 +1,40 @@
+package com.jkcredit.exception;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-14 12:00
+ * @version: V1.0
+ **/
+
+public class BaseException extends RuntimeException {
+
+    /**
+     * 错误信息
+     */
+    private String errorMsg;
+    /**
+     * 服务器状态码
+     */
+    private Integer code;
+
+    public BaseException(String errorMsg) {
+        super(errorMsg);
+        this.errorMsg = errorMsg;
+    }
+
+    public BaseException(Integer code, String errorMsg) {
+        super(errorMsg);
+        this.errorMsg = errorMsg;
+        this.code = code;
+    }
+
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+}

+ 25 - 0
src/main/java/com/jkcredit/exception/GlobalExceptionHandle.java

@@ -0,0 +1,25 @@
+package com.jkcredit.exception;
+
+import com.jkcredit.config.BaseResult;
+import com.jkcredit.utils.ResultUtil;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@ControllerAdvice
+public class GlobalExceptionHandle {
+    @ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public <T> BaseResult<T> handle(Exception e) {
+        if (e instanceof BaseException) {
+            Integer code = 104;
+            BaseException exception = (BaseException) e;
+            if (exception.getCode() != 0) {
+                code = exception.getCode();
+            }
+            return ResultUtil.error(code, e.getMessage());
+        }
+        return ResultUtil.error(500, "服务异常");
+//        return ResultUtil.error(500, e.getMessage() == null ? "服务器内部错误" : e.getMessage());
+    }
+}

+ 22 - 0
src/main/java/com/jkcredit/service/CarService.java

@@ -0,0 +1,22 @@
+package com.jkcredit.service;
+
+import com.jkcredit.config.BaseResult;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-27 10:50
+ * @version: V1.0
+ **/
+public interface CarService {
+
+    /**
+     * 调用http接口
+     * @param params
+     * @return
+     */
+    BaseResult car(Map<String, String> params) throws UnsupportedEncodingException;
+}

+ 126 - 0
src/main/java/com/jkcredit/service/impl/CarServiceImpl.java

@@ -0,0 +1,126 @@
+package com.jkcredit.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.jkcredit.config.BaseResult;
+import com.jkcredit.entity.Car;
+import com.jkcredit.service.CarService;
+import com.jkcredit.utils.DESUtil;
+import com.jkcredit.utils.ResultUtil;
+import com.jkcredit.utils.SignUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-27 10:50
+ * @version: V1.0
+ **/
+@Slf4j
+@Service
+public class CarServiceImpl implements CarService {
+
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Value("${api.app_key}")
+    private String appKey;
+
+    @Value("${api.secret}")
+    private String secret;
+
+    @Value("${api.url}")
+    private String url;
+
+    @Value("${api.ip}")
+    private String ip;
+
+    @Override
+    public BaseResult car(Map<String, String> params) throws UnsupportedEncodingException {
+        long startTime = System.currentTimeMillis();
+        String transactionId = UUID.randomUUID() + String.valueOf(startTime);
+        Car car;
+        try {
+            String sign = params.get("sign");
+            sign = DESUtil.decryptor(new String(sign.getBytes(),"UTF-8"));
+            car = JSONObject.parseObject(sign, Car.class);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("返回数据:{}", JSONObject.toJSONString(ResultUtil.error(9004, "签名错误", transactionId)));
+            return ResultUtil.error(9004, "签名错误", transactionId);
+        }
+
+
+        log.warn("传入参数:{},交易ID:{}", JSONObject.toJSONString(car), transactionId);
+        String result;
+        Map<String, Object> param = SignUtils.getSign(car, params.get("api"), ip, appKey, secret);
+        if (param != null) {
+            //发送http请求 返回jsonObject
+            HttpHeaders headers = new HttpHeaders();
+            headers.add("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
+            log.info("传入接口的json:{}", JSONObject.toJSONString(param));
+            HttpEntity<String> formEntity = new HttpEntity<>(JSONObject.toJSONString(param), headers);
+            JSONObject jsonObject = null;
+            try {
+                jsonObject = restTemplate.postForObject(url, formEntity, JSONObject.class);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            log.info("接口返回:{}", jsonObject);
+
+            return ResultUtil.success(DESUtil.encrypt(jsonObject.toJSONString()), transactionId);
+//            String Q_Message = jsonObject.getString("Q_Message");
+//            JSONObject jsonObject1 = JSON.parseObject(Q_Message);
+//
+//            String ServiceDescript = jsonObject1.getString("ServiceDescript");
+//            JSONObject ServiceDescriptJson = JSON.parseObject(ServiceDescript);
+//
+//            String respData = ServiceDescriptJson.getString("RespData");
+//            JSONObject respDataJson = JSON.parseObject(respData);
+//            //获取接口返回码
+//            String status = respDataJson.getString("status");
+//
+//            long endTime = System.currentTimeMillis();
+//            //计算耗时
+//            long costTime = endTime - startTime;
+//            return ResultUtil.success(DESUtil.encrypt(jsonObject.toJSONString()), transactionId);
+            //如果状态码是200 返回成功数据
+//            if (("200.0").equals(status)) {
+//                result = jsonObject.getString("result");
+//                log.warn("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.success(result, transactionId)), costTime);
+//                return ResultUtil.success(DESUtil.encrypt(result), transactionId);
+//            } else if (("2").equals(status)) {
+//                log.error("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.error(9001, "服务请求参数非法", transactionId)), costTime);
+//                return ResultUtil.error(9001, "服务请求参数非法", transactionId);
+//            } else if (("14").equals(status)) {
+//                log.error("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.error(9001, "服务请求参数非法", transactionId)), costTime);
+//                return ResultUtil.error(9001, "服务请求参数非法", transactionId);
+//            }else if (("10").equals(status)) {
+//                log.error("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.error(9001, "服务请求时间格式有误", transactionId)), costTime);
+//                return ResultUtil.error(9001, "服务请求时间格式有误", transactionId);
+//            }else if (("16").equals(status)) {
+//                log.error("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.error(9001, "用户当日访问该服务成功次数达到上限", transactionId)), costTime);
+//                return ResultUtil.error(9001, "用户当日访问该服务成功次数达到上限", transactionId);
+//            } else {
+//                log.error("返回数据:{},总耗时:{}ms", JSONObject.toJSONString(ResultUtil.error(9002, "服务异常", transactionId)), costTime);
+//                return ResultUtil.error(9002, "服务异常", transactionId);
+//            }
+        } else {
+            log.error("返回数据:{}", JSONObject.toJSONString(ResultUtil.error(9002, "API名称不存在", transactionId)));
+            return ResultUtil.error(9003, "API名称不存在", transactionId);
+        }
+    }
+}

+ 148 - 0
src/main/java/com/jkcredit/utils/DESUtil.java

@@ -0,0 +1,148 @@
+package com.jkcredit.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import sun.misc.BASE64Encoder;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.SecureRandom;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-21 10:48
+ * @version: V1.0
+ **/
+
+public class DESUtil {
+    //
+    /**
+     * 密码,长度要是8的倍数    注意此处为简单密码  简单应用 要求不高时可用此密码
+     * DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,
+     * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力,
+     * 24小时内即可被破解。
+     */
+
+    private static String password = "li3J2uIANKF0WKY6Xs6Wcq7PimJbv2Er";
+
+    public static void main(String args[]) {
+        //待加密内容
+        String str = "{\"plateNumber\":\"\",\"engineNumber\":\"171127C0046\",\"VehicleIdentificationNumber\":\"879725\",\"vin\":\"\"}";
+//        String str = "{\"plateNumber\":\"京FQ5212\"}";
+
+        String result = DESUtil.encrypt(str);
+
+        BASE64Encoder base64en = new BASE64Encoder();
+//        String strs = new String(base64en.encode(result));
+
+        System.out.println("加密后:" + result);
+        //直接将如上内容解密
+        try {
+            String decryResult = DESUtil.decryptor(" QQARbK5XUxtcXldm/A3UOPlyNHgh9RJczYosHQlKNkEL3Yam2CFkDHYUZHoOJh8zEei0/s/WibOB\\r\\nY8Din4Kvc2hbAaYec/AE9rCdnBvsUlVPR+smpBXP5XPrlLpGv31pIFbkr7F3eTvfR6ZJS1XvRMG6\\r\\n+bFI74tT8dtP2jNe7NbTRo2SdRX/XZfos1U2sj06w+6b4W8msDv64ennsawlT3BEQUSCd/w3t+6u\\r\\nMRHV4AHcOKZcdtn+ljENnzEysS/DCB1jh8EcZQdfaeSKrWT/CFgSceglcWhe6D37pr4gL9k/t6mh\\r\\nN3CR2rLbMaZEw9ThQNx5YE6J7L5nEKzCAAzwng==");
+            JSONObject jsonObject = JSON.parseObject(decryResult);
+            String Q_Message = jsonObject.getString("Q_Message");
+            JSONObject jsonObject1 = JSON.parseObject(Q_Message);
+
+            String ServiceDescript = jsonObject1.getString("ServiceDescript");
+            JSONObject ServiceDescriptJson = JSON.parseObject(ServiceDescript);
+            String respData = ServiceDescriptJson.getString("RespData");
+            JSONObject respDataJson = JSON.parseObject(respData);
+            String status = respDataJson.getString("status");
+            System.out.println("解密后:" + status);
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+    }
+
+    /**
+     * @param data
+     * @return
+     * @throws Exception
+     * @Method: encrypt
+     * @Description: 加密数据
+     * @date 2016年7月26日
+     */
+    public static String encrypt(String data) {  //对string进行BASE64Encoder转换
+        byte[] bt = encryptByKey(data.getBytes(), password);
+        BASE64Encoder base64en = new BASE64Encoder();
+        bt = base64en.encode(bt).getBytes();
+        try {
+            return new String(bt,"UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * @param data
+     * @return
+     * @throws Exception
+     * @Method: encrypt
+     * @Description: 解密数据
+     * @date 2016年7月26日
+     */
+    public static String decryptor(String data) throws Exception {  //对string进行BASE64Encoder转换
+        sun.misc.BASE64Decoder base64en = new sun.misc.BASE64Decoder();
+        byte[] bt = decrypt(base64en.decodeBuffer(data), password);
+        String strs = new String(bt,"UTF-8");
+        return strs;
+    }
+
+    /**
+     * 加密
+     *
+     * @param datasource byte[]
+     * @param key        String
+     * @return byte[]
+     */
+    private static byte[] encryptByKey(byte[] datasource, String key) {
+        try {
+            SecureRandom random = new SecureRandom();
+
+            DESKeySpec desKey = new DESKeySpec(key.getBytes());
+            //创建一个密匙工厂,然后用它把DESKeySpec转换成
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey securekey = keyFactory.generateSecret(desKey);
+            //Cipher对象实际完成加密操作
+            Cipher cipher = Cipher.getInstance("DES");
+            //用密匙初始化Cipher对象
+            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
+            //现在,获取数据并加密
+            //正式执行加密操作
+            return cipher.doFinal(datasource);
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 解密
+     *
+     * @param src byte[]
+     * @param key String
+     * @return byte[]
+     * @throws Exception
+     */
+    private static byte[] decrypt(byte[] src, String key) throws Exception {
+        // DES算法要求有一个可信任的随机数源
+        SecureRandom random = new SecureRandom();
+        // 创建一个DESKeySpec对象
+        DESKeySpec desKey = new DESKeySpec(key.getBytes());
+        // 创建一个密匙工厂
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+        // 将DESKeySpec对象转换成SecretKey对象
+        SecretKey securekey = keyFactory.generateSecret(desKey);
+        // Cipher对象实际完成解密操作
+        Cipher cipher = Cipher.getInstance("DES");
+        // 用密匙初始化Cipher对象
+        cipher.init(Cipher.DECRYPT_MODE, securekey, random);
+        // 真正开始解密操作
+        return cipher.doFinal(src);
+    }
+}

+ 70 - 0
src/main/java/com/jkcredit/utils/HttpClientUtils.java

@@ -0,0 +1,70 @@
+package com.jkcredit.utils;
+
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContextBuilder;
+ 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * https 忽略证书
+ * @author sunzhaoning
+ */
+public class HttpClientUtils {
+ 
+    public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
+        HttpClientBuilder b = HttpClientBuilder.create();
+ 
+        // setup a Trust Strategy that allows all certificates.
+        //
+        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+            @Override
+            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+                return true;
+            }
+        }).build();
+        b.setSSLContext(sslContext);
+ 
+        // don't check Hostnames, either.
+        //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
+        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
+ 
+        // here's the special part:
+        //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
+        //      -- and create a Registry, to register it.
+        //
+        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                .register("https", sslSocketFactory)
+                .build();
+ 
+        // now, we create connection-manager using our Registry.
+        //      -- allows multi-threaded use
+        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
+        connMgr.setMaxTotal(200);
+        connMgr.setDefaultMaxPerRoute(100);
+        b.setConnectionManager( connMgr);
+ 
+        // finally, build the HttpClient;
+        //      -- done!
+        CloseableHttpClient client = b.build();
+ 
+        return client;
+    }
+ 
+}

+ 55 - 0
src/main/java/com/jkcredit/utils/Md5Utils.java

@@ -0,0 +1,55 @@
+package com.jkcredit.utils;
+
+import java.security.MessageDigest;
+
+/**
+ * @description: MD5加密
+ * @author:
+ * @create: 2019-05-14 11:05
+ * @version: V1.0
+ **/
+
+public class Md5Utils {
+
+    /**
+     * 生成md5,全部大写
+     * @param message
+     * @return
+     */
+    public static String md5(String message) {
+        try {
+            // 1 创建提供信息摘要算法的对象,初始化为md5算法对象
+            MessageDigest md = MessageDigest.getInstance("MD5");
+
+            // 2 将消息变成byte数组
+            byte[] input = message.getBytes();
+
+            // 3 计算后获得字节数,这就是那128位了
+            byte[] buff = md.digest(input);
+
+            // 4 把数组每字节(一个字节占八位)换16进制连成md5字符
+            return byte2hex(buff);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 二进制转十六进制字符
+     * @param bytes
+     * @return
+     */
+    private static String byte2hex(byte[] bytes) {
+        StringBuilder sign = new StringBuilder();
+        for (int i = 0; i < bytes.length; i++) {
+            String hex = Integer.toHexString(bytes[i] & 0xFF);
+            if (hex.length() == 1) {
+                sign.append("0");
+            }
+            sign.append(hex.toUpperCase());
+        }
+        return sign.toString();
+    }
+
+
+}

+ 39 - 0
src/main/java/com/jkcredit/utils/ResultUtil.java

@@ -0,0 +1,39 @@
+package com.jkcredit.utils;
+
+import com.jkcredit.config.BaseResult;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-14 11:59
+ * @version: V1.0
+ **/
+
+public class ResultUtil {
+
+    public static <T> BaseResult<T> success(T data,String transactionId) {
+        return commonResult( 1000, "请求成功", data,transactionId);
+    }
+
+    public static <T> BaseResult<T> error(String errorMsg) {
+        return error(200, errorMsg,null);
+    }
+
+    public static <T> BaseResult<T> error(Integer code, String errorMsg) {
+        return commonResult( code, errorMsg, null,null);
+    }
+
+    public static <T> BaseResult<T> error(Integer code, String errorMsg,String transactionId) {
+        return commonResult( code, errorMsg, null,transactionId);
+    }
+
+    private static <T> BaseResult<T> commonResult( Integer code, String errMsg, T data,String transactionId) {
+        BaseResult<T> result = new BaseResult<>();
+//        result.setStatus(status);
+        result.setCode(code);
+        result.setMsg(errMsg);
+        result.setData(data);
+        result.setTransactionId(transactionId);
+        return result;
+    }
+}

+ 146 - 0
src/main/java/com/jkcredit/utils/SignUtils.java

@@ -0,0 +1,146 @@
+package com.jkcredit.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.jkcredit.entity.Car;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @description: 构建签名辅助类
+ * @author: sunzhaoning
+ * @create: 2019-05-14 11:06
+ * @version: V1.0
+ **/
+@Slf4j
+public class SignUtils {
+
+    /**
+     * 构建参数
+     * @param car 入参实体
+     * @param apiName api 名称
+     * @param ip ip地址
+     * @param appKey appKey
+     * @param secret secret
+     * @return Map
+     */
+    public static Map<String, Object> getSign(Car car,String apiName,String ip,String appKey,String secret) throws UnsupportedEncodingException {
+        String sign;
+        // 业务参数
+        Map<String, String> jsonMap = new HashMap<>(5);
+        Map<String, Object> param = new HashMap<>(12);
+        //api 名称
+        String carInfo = "carInfo";
+        String stolenCar ="stolenCar";
+        String isMortgage ="mortgage";
+
+        if((carInfo).equals(apiName)){
+            jsonMap.put("FDJH", car.getEngineNumber());
+            jsonMap.put("CLSBDH", car.getVehicleIdentificationNumber());
+            jsonMap.put("CJH", car.getVin());
+            jsonMap.put("HPHM", car.getPlateNumber());
+            param.put("name", "gab_jdcxxcx");
+            param.put("returnColumns", "HPZL,CCDJRQ,CLPP1,FZJG,DYBJ");
+        }else if((stolenCar).equals(apiName)){
+            jsonMap.put("FDJH", car.getEngineNumber());
+            jsonMap.put("CJH", car.getVin());
+            jsonMap.put("HPHM", car.getPlateNumber());
+            jsonMap.put("CLSBDH", car.getVehicleIdentificationNumber());
+            param.put("name", "gab_bdqc");
+            param.put("returnColumns", "FDJH,CJH,HPHM");
+        }else if((isMortgage).equals(apiName)){
+            jsonMap.put("CLSBDH",car.getVehicleIdentificationNumber());          jsonMap.put("FDJH",car.getEngineNumber());
+            jsonMap.put("HPHM", car.getPlateNumber());
+            param.put("name", "gab_jdcsfdy");
+            param.put("returnColumns", "DYBJ");
+        }else{
+            return null;
+        }
+
+        Map<String, String> map = sortMapByKey(jsonMap);
+        String json = JSON.toJSONString(map);
+
+        Map<String,String> userInfoMap = new HashMap<>(2);
+        userInfoMap.put("ip",ip);
+        userInfoMap.put("mac","00-23-24-8B-C4-81");
+
+        String userInfo = JSON.toJSONString(userInfoMap);
+
+        // 请求参数拼接
+        param.put("app_key", appKey);
+        param.put("data", json);
+//        param.put("timestamp", "2019-05-27 16:17:27");
+        param.put("timestamp", getTime());
+        param.put("userInfo", userInfo);
+        param.put("version", "1.0");
+        param.put("format", "json");
+
+        //进行签名
+        sign = SignUtils.buildSign(param, secret);
+//        log.info("签名后数据:{}",sign);
+
+        //将加密后的签名放入map
+        param.put("sign", sign);
+
+        return param;
+    }
+
+    /**
+     * 构建签名
+     * @param paramsMap 参数
+     * @param secret 密钥
+     * @throws IOException
+     */
+    public static String buildSign(Map<String, ?> paramsMap, String secret) {
+        Set<String> keySet = paramsMap.keySet();
+        List<String> paramNames = new ArrayList<>(keySet);
+
+        Collections.sort(paramNames);
+
+        StringBuilder paramNameValue = new StringBuilder();
+
+        for (String paramName : paramNames) {
+            paramNameValue.append(paramName).append(paramsMap.get(paramName));
+        }
+        String source = secret + paramNameValue.toString() + secret;
+
+        return Md5Utils.md5(source);
+    }
+
+    /**
+     * 获取当前时间 格式yyyy-MM-dd HH:mm:ss
+     * @return
+     */
+    public static String getTime() {
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+    }
+
+    /**
+     * 使用 Map按key进行排序
+     * @param map
+     * @return
+     */
+    public static Map<String, String> sortMapByKey(Map<String, String> map) {
+        if (map == null || map.isEmpty()) {
+            return null;
+        }
+
+        Map<String, String> sortMap = new TreeMap<>(
+                new MapKeyComparator());
+
+        sortMap.putAll(map);
+
+        return sortMap;
+    }
+    static class MapKeyComparator implements Comparator<String>{
+
+        @Override
+        public int compare(String str1, String str2) {
+
+            return str1.compareTo(str2);
+        }
+    }
+}

+ 15 - 0
src/main/resources/application.yml

@@ -0,0 +1,15 @@
+api:
+  app_key: 583311377037262848
+  secret: 7e8f7db116a14c44881b6a4657ed5aa4
+  url: https://59.255.92.133:18080/ZW_VehicleProxy/api/v1/
+  ip: 59.255.69.5
+spring:
+  application:
+    name: car-credit
+server:
+  undertow:
+    accesslog:
+      dir: logs
+      enabled: false
+    max-http-post-size: 0
+  port: 18881

+ 124 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="gb2312"?>
+<configuration debug="false" scan="false">
+    <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
+	<property name="log.path" value="logs/" />
+	<!-- 彩色日志格式 -->
+	<property name="CONSOLE_LOG_PATTERN"
+			  value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
+	<!-- 彩色日志依赖的渲染类 -->
+	<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+	<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+	<conversionRule conversionWord="wEx"
+					converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- Console log output -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+        </encoder>
+    </appender>
+
+<!--    &lt;!&ndash; Log file debug output &ndash;&gt;-->
+<!--    <appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
+<!--        &lt;!&ndash; 过滤器,只记录WARN级别的日志 &ndash;&gt;-->
+<!--        <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
+<!--            <level>INFO</level>-->
+<!--            <onMatch>ACCEPT</onMatch>-->
+<!--            <onMismatch>DENY</onMismatch>-->
+<!--        </filter>-->
+<!--        <file>${log.path}/info.log</file>-->
+<!--        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
+<!--            <fileNamePattern>${log.path}/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>-->
+<!--            <maxFileSize>50MB</maxFileSize>-->
+<!--            <maxHistory>30</maxHistory>-->
+<!--        </rollingPolicy>-->
+<!--        <encoder>-->
+<!--            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!-- Log file error output -->
+    <appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/error/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/error/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/project/project.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/project/%d{yyyy-MM}/project.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="sourceLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/source/source.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/source/%d{yyyy-MM}/source.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="queryLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/query/query.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/query/%d{yyyy-MM}/query.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date %msg%n</pattern>
+        </encoder>
+    </appender>
+    <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
+    <root level="INFO">
+        <appender-ref ref="console" />
+<!--        <appender-ref ref="info" />-->
+<!--        <appender-ref ref="warn" />-->
+        <appender-ref ref="info" />
+    </root>
+
+    <logger name="com.jkcredit.controller.CarInfoController" level="ERROR">
+        <appender-ref ref="errorLog"/>
+    </logger>
+    <logger name="com.jkcredit.controller.CarInfoController" level="WARN">
+        <appender-ref ref="queryLog"/>
+    </logger>
+    <logger name="com.jkcredit.controller.CarInfoController" level="INFO">
+        <appender-ref ref="sourceLog"/>
+    </logger>
+
+
+</configuration>

+ 16 - 0
src/test/java/com/jkcredit/CarCreditApplicationTests.java

@@ -0,0 +1,16 @@
+package com.jkcredit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class CarCreditApplicationTests {
+
+    @Test
+    public void contextLoads() {
+    }
+
+}