基于Spring的三方平台接口对接方法(OkHttp/RestTemplate/视图)

本文介绍了三方平台接口对接方法,一是基于OkHttp请求工具及dom4j报文封装解析xml的方法,二是采用RestTemplate方法封装请求,三是采用建立视图和从库数据源的方式查询。

一、OkHttp请求工具及dom4j报文封装解析

1、 依赖引入

java 复制代码
<!-- okhttp3包 -->

<dependency>

    <groupId>com.squareup.okhttp3</groupId>

    <artifactId>okhttp</artifactId>

    <version>4.9.3</version>

    <scope>compile</scope>

</dependency>
java 复制代码
<dependency>

    <groupId>org.dom4j</groupId>

    <artifactId>dom4j</artifactId>

    <version>2.1.4</version>

</dependency>

2、OkHttp请求工具类

java 复制代码
package com.inspur.common.utils.okhttp;





import okhttp3.*;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;



import java.io.File;

import java.io.IOException;

import java.util.Map;

import java.util.concurrent.TimeUnit;



/**

 * OkHttp封装,调用示例OkHttpUtil.postJson(...)


 */

public class OkHttpUtil {



    private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);



    private static final byte[] LOCKER = new byte[0];

    private static volatile OkHttpClient okHttpClient;



    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");





    private OkHttpUtil() {



    }



    private static OkHttpClient getOkHttpClient() {

        if (okHttpClient == null) {

            synchronized (LOCKER) {

                if (okHttpClient == null) {

                    OkHttpClient.Builder ClientBuilder = new OkHttpClient.Builder();

                    ClientBuilder.readTimeout(30, TimeUnit.SECONDS);//读取超时

                    ClientBuilder.connectTimeout(30, TimeUnit.SECONDS);//连接超时

                    ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//写入超时

                    okHttpClient = ClientBuilder.build();

                }

            }

        }

        return okHttpClient;

    }



    /**

     * 发送get请求

     *

     * @param url

     * @param json

     * @return

     * @throws IOException

     */

    public static Result<String> get(String url) throws IOException {

        logger.debug("请求url:{}", url);



        Request request = new Request.Builder()

                .url(url)

                .get()

                .build();



        return execute(request);

    }



    /**

     * 发送get请求,带参数

     *

     * @param url

     * @param json

     * @return

     * @throws IOException

     */

    public static Result<String> get(String url, Map<String, String> params) throws IOException {

        logger.debug("请求url:{}", url);



        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();

        for (Map.Entry<String, String> entry : params.entrySet()) {

            //追加表单信息

            urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());

        }



        Request request = new Request.Builder()

                .url(urlBuilder.build())

                .build();





        return execute(request);

    }





    /**

     * 发送json请求

     *

     * @param url

     * @param json

     * @return

     * @throws IOException

     */

    public static Result<String> postJson(String url, String json) throws IOException {

        logger.debug("请求url:{},请求体:{}", url, json);



        RequestBody requestBody = RequestBody.create(json,JSON);

        Request request = new Request.Builder()

                .url(url)

                .post(requestBody)

                .build();



        return execute(request);

    }





    public static Result<String> postXml(String url, String xml) throws IOException {

        RequestBody requestBody = RequestBody.create(xml, XML);

        Request request = new Request.Builder()

                .url(url)

                .post(requestBody)

                .build();



        return execute(request);

    }



    /**

     * 发送form表单post请求

     *

     * @param url

     * @param params

     * @return

     * @throws IOException

     */

    public static Result<String> post(String url, Map<String, String> params) throws IOException {

        logger.debug("请求地址:{};", url);

        //创建一个FormBody.Builder

        FormBody.Builder builder = new FormBody.Builder();

        for (Map.Entry<String, String> entry : params.entrySet()) {

            //追加表单信息

            builder.add(entry.getKey(), entry.getValue());

        }

        //生成表单实体对象

        RequestBody formBody = builder.build();



        Request request = new Request.Builder()

                .url(url)

                .post(formBody)

                .build();

        return execute(request);

    }





    /**

     * 发送form表单post请求

     *

     * @param url

     * @param params

     * @return

     * @throws IOException

     */

    public static Result<String> postWithHeader(String url, Map<String, String> params, String... headers) throws IOException {

        logger.debug("请求url:{};", url);

        //创建一个FormBody.Builder

        FormBody.Builder builder = new FormBody.Builder();

        for (Map.Entry<String, String> entry : params.entrySet()) {

            //追加表单信息

            builder.add(entry.getKey(), entry.getValue());

        }

        //生成表单实体对象

        RequestBody formBody = builder.build();



        Request request = new Request.Builder()

                .url(url)

                .headers(Headers.of(headers))

                .post(formBody)

                .build();



        return execute(request);

    }



    /**

     * 发送form表单post请求

     *

     * @param url

     * @param params

     * @return

     * @throws IOException

     */

    public static Result<String> postFile(String url, String fileName, File file, Map<String, String> params) throws IOException {

        logger.debug("请求url:{};", url);



        MultipartBody.Builder builder = new MultipartBody.Builder();



        builder.addFormDataPart(fileName, fileName, RequestBody.create(MediaType.parse("application/octet-stream"), file));



        if (params != null) {

            for (Map.Entry<String, String> entry : params.entrySet()) {

                //追加表单信息

                builder.addFormDataPart(entry.getKey(), entry.getValue());

            }



        }



        MultipartBody multipartBody = builder.build();



        Request request = new Request.Builder()

                .url(url)

                .post(multipartBody)

                .build();



        return execute(request);

    }



    private static Result<String> execute(Request request) {

        Result<String> result = new Result();

        try (Response response = OkHttpUtil.getOkHttpClient().newCall(request).execute()) {

            logger.debug("{} 请求结果:{}", request.url().url(), response);



            if (response.isSuccessful()) {

                ResponseBody body = response.body();

                if (body != null) {

                    result = Result.ok(response.message(), body.string());

                }else {

                    result = Result.ok(response.message());

                }

            }else {

                result = Result.fail(response.code(),response.message());

            }

        } catch (Exception e) {

            result = Result.fail(e.getMessage());

        }

        return result;

    }

}

3、基于dom4j解析和封装xml

(1)xml文件报文示例

/admin-module/src/main/resources/nc/classStudent.xml

XML 复制代码
<?xml version="1.0" encoding='UTF-8'?>
<ufinterface account="tpy63_wzx0731" billtype="4D" filename="" groupcode="" isexchange="Y" replace="Y" roottag="" sender="gyhlw">
<classInfo>
    <school>市第一中学</school>
    <city>济南</city>
    <location>2楼</location>
</classInfo>
<students>
    <student name="zhangsan" age="18"></student>
    <student name="lisi" age="19"></student>
</students>

</ufinterface>
(2)构建封装xml报文文件
java 复制代码
public String buildXml(){

// 创建saxReader对象

SAXReader reader = new SAXReader();

try (InputStream classInfo = new ClassPathResource("nc/classStudent.xml").getInputStream()) {

        // 通过read方法读取一个文件 转换成Document对象

        Document document = reader.read(classInfo);

        // 获取根节点元素对象

        Element node = document.getRootElement();



        // 根节点下的一级子节点

        Element classInfo = node.element("classInfo");   // 根节点下的子节点 classInfo

        Element students = node.element("students");   // 根节点下的子节点 students



        // 一级子节点classInfo 下属二级节点

        students.element("school").setText("市第一中学");

        students.element("city").setText("济南");

        students.element("location").setText("2楼");



        // 一级子节点students 下属二级节点

        // 以此添加成List并设置属性

        List<Student> st = ArrayList<T> obj = new ArrayList<Student>() {{

        add(new Student("zhangsan",18));

        add(new Student("lisi",19));

    }};



    students.stream().forEach(student -> {

        root.addElement("student")

        .addAttribute("name", student.getName())

        .addAttribute("age", String.valueOf(student.getAge()))

    });



    // 生成xml对象

    String xml = document.asXML();

    logger.info("生成XML:\n{} ", xml);

        }

}
(3)okHttp三方接口请求
(4)xml报文读取解析
java 复制代码
public Object handlerReturn() {

        try {

/*   直接读取文件解析

 // 创建SAXReader

        SAXReader saxReader = SAXReader.createDefault();

        // 将xml解析为树

        Document document = saxReader.read("xml/students.xml");*/

        String xml = this.buildXml();

        // 三方接口请求地址

        String url = "http://110.10.1.11:8888/service/xxx"

        // 1、请求发送

        Result<String>  result = OkHttpUtil.postXml(url, xml);



        if (result.isOk()) {

        String resMess = result.getData();

        logger.info("调用结果:{}", resMess);



        // resMess实际为classStudent.xml文件格式内容

        Document respXml = DocumentHelper.parseText(resMess);

        Element rootElement = respXml.getRootElement();



        // 2、获取根节点下的一级子节点

        Element classInfo = rootElement.element("classInfo");   // 根节点下的子节点 classInfo

        Element students = rootElement.element("students");   // 根节点下的子节点 students



        // 3、获取一级子节点classInfo 下属二级节点属性

        String school = classInfo.elementText("school");

        String city = classInfo.elementText("city");

        String location = classInfo.elementText("location");



        // 4、获取一级子节点students,遍历下属二级节点student列表并获取属性值

        List<Element> eles = students.elements();

        List<Student> students = new ArrayList<>();

        // 遍历子节点列表

        for(Element ele : eles){

            // 读取节点属性

            String name = element.attributeValue("name");

            Interger age = element.attributeValue("age");

            

            Student stu = new Student(name,age);

            students.add(stu)

        }

        }

        } catch (DocumentException | IOException e) {

        logger.error("调用接口异常", e);

        }

        

        // 5、解析结果值构建对应实体类或map

        HashMap resObj = new HashMap<>();

        resObj.put("students",students);

        resObj.put("school",school);

        return resObj;

        }

二、 RestTemplate

OutInterfaceDomain 实体类根据接口规范自行组装定义

1、依赖

XML 复制代码
<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

</dependency>

2、使用

java 复制代码
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import org.springframework.web.client.RestTemplate;



public class OutInterfaceService {

@Autowired
private RestTemplate restTemplate;

private String url = "http://110.1.1.129:8087/DataStandard/*****";

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);





// 要传递的业务内容

Map<String, Object> columnMap = new HashMap<>();

columnMap.put("DEVICE_NO", factoryDevice.getDeviceNo());



// 按接口规范组装

OutInterfaceDomain outInterfaceDomain = new OutInterfaceDomain();

outInterfaceDomain.setColumns(columnMap);



String contentJson = JSON.toJSONString(outInterfaceDomain, SerializerFeature.WriteMapNullValue);
HttpEntity<String> httpEntity = new HttpEntity<>(contentJson, httpHeaders);



// 调用三方接口

restTemplate.postForEntity(url, httpEntity, String.class);



}

三、sql视图

在原表建立视图,并创建新用户,赋予只读权限。使用@DataSource来切换数据库查询。

1、创建视图和用户并赋予权限

sql 复制代码
grant select on [view] to [username];//查询视图权限

grant connect to [username];//连接数据库权限   



# 创建设备视图

create or replace view factory_device_view as

select * from factory_device;

comment on table factory_device_view is '设备视图';

SELECT * FROM all_tab_cols WHERE table_name ='FACTORY_DEVICE_VIEW';

# 创建用户

create user jtgViewer identified by password123$

# 赋予权限

GRANT SELECT ON jtg.factory_device_view TO jtgViewer; 

grant connect to jtgViewer

2、配置文件

XML 复制代码
# 从库数据源
slave:
  # 从数据源开关/默认关闭
  enabled: true
  url: jdbc:mysql://192.168.100.200:3306/esis_tjzg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
  username: root
  password: Inspur@2023

3、查询使用

java 复制代码
@DataSource(DataSourceType.SLAVE)

public List<Map<String,Object>> selectOutAmountByMaterial(TImMaterialrequestbill tImMaterialrequestbill);
相关推荐
知兀几秒前
【MybatisPlus】后端用枚举类,数据库用tinyint,存在枚举类型转换
java
StockTV2 分钟前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
User_芊芊君子5 分钟前
【OpenAI 把 AI 玩明白了】:自主推理 + 动态知识图谱,这 4 个技术突破要颠覆行业
java·人工智能·知识图谱
c++之路38 分钟前
C++20概述
java·开发语言·c++20
Championship.23.2442 分钟前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试
橘子海全栈攻城狮1 小时前
【最新源码】养老院系统管理A013
java·spring boot·后端·web安全·微信小程序
逻辑驱动的ken1 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
冷雨夜中漫步2 小时前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
直奔標竿2 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
one_love_zfl2 小时前
java面试-微服务组件篇
java·微服务·面试