基于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);
相关推荐
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹3 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白664 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp5 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶5 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb