栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA版海关179号对接流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA版海关179号对接流程

代码借鉴海关179对接API.(如有侵权马上删除)

步骤
  • 拿到ukey(运营或产品哪里应该会有)
  • 获取开发文档179号开发文档
  • 开发接收海关请求接口(按文档要求不能有端口号)
  • 组装数据进行加签
  • 拼接加签数据上报
  • 完成

以上文档等不多介绍主要是开发(身为CV工程师直接上代码)

接收海关请求
接收海关请求并存储请求(因为加签需要在本地而接收请求要在开放服务器所以使用mq传输数据)

@PostMapping(value = "/platDataOpen")
    @ResponseBody
    public JSONObject platDataOpen(@RequestParam String openReq){

        //解析获取数据
        openReq = StringUtils.replace(openReq, """, """);
        JSONObject jsonObject = JSONObject.parseObject(openReq);
        String orderNo = jsonObject.getString("orderNo");
        String sessionID = jsonObject.getString("sessionID");
        Long serviceTime = jsonObject.getLong("serviceTime");

        System.out.println(orderNo+sessionID+serviceTime);

        //查询是否有订单
        String source = customsService.insertCustoms(orderNo,sessionID,serviceTime);

        JSONObject result = new JSONObject();
        if (source.equals("10000")){
            result.put("code", "10000");
            result.put("message", "");
        }else{
            result.put("code", "205");
            result.put("message", "没有此订单");
        }
        result.put("serviceTime", System.currentTimeMillis());

        return result;
    }
	@Resource
    RabbitTemplate rabbitTemplate;

 
    @Override
    public String insertCustoms(String orderNo, String sessionID, Long serviceTime) {
        logger.info("海关抽查订单"+orderNo);

        OmsOrderExample omsOrderExample = new OmsOrderExample();
        omsOrderExample.createCriteria().andOrderSnEqualTo(orderNo);
        List omsOrders = omsOrderMapper.selectByExample(omsOrderExample);
        //判断是否有指定订单
        if(omsOrders.size()>0){

            //查询是否存在订单号
            PaycheckExample example = new PaycheckExample();
            example.createCriteria().andOrderNoEqualTo(orderNo);
            List paychecks = paycheckMapper.selectByExample(example);
            if(paychecks.size()>0){
                paychecks.get(0).setSessionId(sessionID);
                int num = paycheckMapper.updateByPrimaryKey(paychecks.get(0));
                if(num>0){
                    System.out.println("修改成功");
                }
            }else{
                Paycheck paycheck = new Paycheck();
                paycheck.setOrderNo(orderNo);
                paycheck.setSessionId(sessionID);
                paycheck.setAddTime(new Date());
                paycheck.setStatus((byte) 0);
                paycheck.setBackTime(new Date());
                int num = paycheckMapper.insert(paycheck);
                if (num>0){
                    System.out.println("添加成功");

                }
            }

            logger.info("发送消息到CUSTOMS_EXPORT_QUEUE");
			rabbitTemplate.convertAndSend(DirectRabbitConfig.CUSTOMS_EXPORT_EXCHANGE,DirectRabbitConfig.CUSTOMS_EXPORT_ROUTING,orderId);



            //webscoketTest(orderNo);
            return "10000";
        }

            return "205";
    }

创建实体类存放数据

import lombok.Data;

import java.util.List;


@Data
@JSONType(orders={"sessionID","payExchangeInfoHead","payExchangeInfoLists","serviceTime","certNo","signValue"})
public class HaiguanVO {
	//@JSONType很重要作用就是JSON化的时候数据的排序
	//@JSonType(orders={"sessionID","payExchangeInfoHead","payExchangeInfoLists","serviceTime","certNo","signValue"})

    
    public String sessionID;

    public PayExchangeInfoHead payExchangeInfoHead;

    public List payExchangeInfoLists;
    
    public String serviceTime;
    
    public String certNo;
    
    public String signValue;
    
}
package com.example.customsspotcheck.vo;

import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;


@Data
@JSONType(orders={"guid","initalRequest","initalResponse","ebpCode","payCode","payTransactionId","totalAmount","currency","verDept","tradingTime"})
public class PayExchangeInfoHead {

    
    public String guid;
    
    public String initalRequest;
    
    public String initalResponse;
    
    public String ebpCode;
    
    public String payCode;
    
    public String payTransactionId;
    
    public Double totalAmount;
    
    public String currency;
    
    public String verDept;
    
    //public String payType;
    
    public String tradingTime;
    
    //public String note;
}

package com.example.customsspotcheck.vo;

import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;

import java.util.List;


@Data
@JSONType(orders={"orderNo","goodsInfo","recpAccount","recpCode","recpName"})
public class PayExchangeInfoLists {

    
    public String orderNo;
    
    public List goodsInfo;
    
    public String recpAccount;
    
    public String recpCode;
    
    public String recpName;
    
}

package com.example.customsspotcheck.vo;

import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;


@Data
@JSONType(orders={"gname","itemlink"})
public class goodsInfo {

    
    public String gname;
    
    public String itemlink;

}

以上是全部的实体类(通过自己的情况查询数据添加即可)

接下来是加签
加签是获取signValue海关会验签
加签有js加签 websocket加签 (本人纯后端前端不太会所以使用websocket加签)
websocket加签要有一个操作员的卡(一个U盘)
插入后启动


就会在本地开放两个个websocket服务
请求地址:
ws://127.0.0.1:61232
wss://wss.singlewindow.cn:61231

编写websocket加签代码

首先组装数据

package com.example.customsspotcheck.service.impl;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import com.alibaba.fastjson.JSONObject;
import com.example.customsspotcheck.mapper.PaycheckDao;
import com.example.customsspotcheck.service.HaiguanService;
import com.example.customsspotcheck.util.HaiguanSign;
import com.example.customsspotcheck.vo.HgCheckVO;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.NamevaluePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNamevaluePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;


@Service
public class HaiguanServiceImpl implements HaiguanService {


    @Resource
    HaiguanSign haiguanSign;

    @Value(value = "${spring.customs.haiguan.certNo}")
    private String certNo;
    @Value(value = "${spring.customs.haiguan.password}")
    private String password;
    @Value(value = "${spring.customs.haiguan.uploadUrl}")
    private String uploadUrl;

    @Resource
    PaycheckDao paycheckDao;

    
    @Override
    public void repDataApply(HgCheckVO entity) {

        
        StringBuffer sb = new StringBuffer();
        sb.append(""sessionID":"").append(entity.getSessionID()).append(""").append("||");
        String headerString = JSON.toJSONString(entity.getPayExchangeInfoHead(), SerializerFeature.SortField);
        sb.append(""payExchangeInfoHead":"").append(headerString).append(""").append("||");
        String listString = JSON.toJSONString(entity.getPayExchangeInfoLists(), SerializerFeature.SortField);
        sb.append(""payExchangeInfoLists":"").append(listString).append(""").append("||");
        sb.append(""serviceTime":"").append(entity.getServiceTime()).append(""");
        String signValue = sb.toString();

        //组装加签数据
        Map args = new java.util.HashMap<>();
        args.put("inData", signValue);
        args.put("passwd", password);
        JSONObject epdata = new JSONObject(true);
        epdata.put("_method", "cus-sec_SpcSignDataAsPEM");
        epdata.put("_id", 1);
        epdata.put("args", args);

        //加签(使用websocket加签)
        haiguanSign.sign(epdata,entity);


    }


    
    @Override
    public void shangbao(HgCheckVO entity) {

		//吧获取到的全部数据转JSON然后上报给海关
        System.out.println("---海关179数据上报数据:payExInfoStr=" + JSON.toJSONString(entity));

        try {
            List param = new ArrayList();
            //组装数据
            param.add(new BasicNamevaluePair("payExInfoStr", JSON.toJSONString(entity)));
            CloseableHttpClient client = getHttpsClient();
            HttpPost post = new HttpPost(uploadUrl);
            post.setEntity(new UrlEncodedFormEntity(param,Consts.UTF_8));
            try {
                CloseableHttpResponse xx = client.execute(post);
                if(HttpStatus.SC_OK == xx.getStatusLine().getStatusCode()) {
                    String result = EntityUtils.toString(xx.getEntity(), Consts.UTF_8);
                    System.out.println("---海关179数据上报结果:" + result);
                    //解析返回数据表
                    Map mapType = JSON.parseObject(result,Map.class);
                    //获取订单id
                    String OederSn = entity.getPayExchangeInfoLists().get(0).getOrderNo();
                    System.out.println(mapType.get("code"));
                    if(mapType.get("code").equals("10000")){
                        System.out.println("上传成功:"+OederSn);
                        //修改上报状态
                        paycheckDao.updatePaycheck(OederSn,1);
                    }else{
                        System.out.println("上传失败:"+OederSn);
                        //修改上报状态
                        paycheckDao.updatePaycheck(OederSn,2);
                    }
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (Exception e){

        }
    }

    private static CloseableHttpClient getHttpsClient(){
        SSLConnectionSocketFactory sslsf = null;
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();

            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }

                @Override
                public void verify(String host, SSLSocket ssl) throws IOException {
                }

                @Override
                public void verify(String host, X509Certificate cert) throws SSLException {
                }

                @Override
                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
                }
            });
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
}
package com.example.customsspotcheck.util;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.example.customsspotcheck.service.HaiguanService;
import com.example.customsspotcheck.vo.HgCheckVO;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import javax.annotation.Resource;



@Service
public class HaiguanSign {

    private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(HaiguanSign.class);

    
    public static final Integer TIME_OUT = 3 * 60 * 1000;
    
    public static final Integer TIME_STEP = 10;

    @Value(value = "${spring.customs.haiguan.sign.wsUrl}")
    private String wsUrl;

    @Value(value = "${spring.customs.haiguan.certNo}")
    private String certNo;

    @Resource
    HaiguanService haiguanService;


    
    private Map clientPool = new HashMap<>();

    
    public String sign(JSONObject value, HgCheckVO entity) {
        System.out.println("请求加签报文->" + value);

        WebSocketClient client = clientPool.get(wsUrl);
        if (client != null && client.isConnecting() && client.isOpen()) {
            client.send(String.valueOf(value));
        } else {
            try {
                client = new WebSocketClient(new URI(wsUrl)) {
                    @Override
                    public void onOpen(ServerHandshake shake) {
                        // TODO Auto-generated method stub
                        System.out.println("握手...");
                        for (Iterator it = shake.iterateHttpFields(); it.hasNext();) {
                            String key = it.next();
                            System.out.println(key + "->" + shake.getFieldValue(key));
                        }
                    }

                    @Override
                    public void onMessage(String message) {
                        // TODO Auto-generated method stub
                        if (!StringUtils.isEmpty(message)) {
                            System.out.println("接收到消息:" + message);
                            JSONObject jsonObject = JSON.parseObject(String.valueOf(message));
                            Integer id = jsonObject.getInteger("_id");
                            if (id != null && id == 0) {
                                System.out.println("根据海关ws报文,第一次回复为握手通知,并非'加签'信息!");//第一次(id=0)
                            } else if (id != null && id == 1) {
                                JSONArray data = jsonObject.getJSONObject("_args").getJSONArray("Data");
                                String signValue = data.getString(0);
                                
                                entity.setCertNo(certNo);
                                
                                entity.setSignValue(signValue);
                                //上报数据
                                haiguanService.shangbao(entity);

                            }
                        }
                    }

                    @Override
                    public void onClose(int code, String reason, boolean remote) {
                        // TODO Auto-generated method stub
                        System.out.println("-----------close()");
                    }

                    @Override
                    public void onError(Exception ex) {
                        // TODO Auto-generated method stub
                        System.out.println("-----------onError:"+ex.getMessage());
                    }
                };
            } catch (URISyntaxException e) {
                e.printStackTrace();
                System.out.println("--------->websocket client exception.");
            }

            client.connect();
            Integer count = 0;
            // 阻塞等待OPEN
            while (!client.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
                try {
                    count += TIME_STEP;
                    Thread.sleep(TIME_STEP);
                    if (count >= TIME_OUT) {
                        LOGGER.info("error-{}", new Exception("WS服务器连接超时!或服务器已经关闭"));
                        break;
                    }
                } catch (InterruptedException e) {
                    LOGGER.error("发送信息异常-{}", e);
                }
            }

            client.send(String.valueOf(value));
            // 放入缓存
            clientPool.put(wsUrl, client);
        }
        return "";
    }
}

以上就是海关179对接如有疑问可以留言(海关179对接过最坑的没有之一)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/444911.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号