WebClient简单使用以及jackson-dataformat-xml使用

        最近做项目过程中遇到一个需求,需要在java端向外部服务器发送restful请求,并且请求体和返回体都是xml格式数据。经过一番查询,决定使用WebClient和jackson-dataformat-xml解决问题。

一、安装依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>

二、使用webClient

项目需要使用https,忽略ssl验证。

package com.sy.ai.vcm.utils;

import com.sy.ai.common.exception.http.ArgumentsException;
import com.sy.ai.common.properties.ProjProperties;
import com.sy.ai.common.constant.ResultCode;
import com.sy.ai.common.utils.XmlUtils;
import com.sy.ai.common.exception.http.HttpException;
import com.sy.ai.vcm.entity.request.VcmBaseRequestEntity;
import com.sy.ai.vcm.entity.response.VcmBaseResponseEntity;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import javax.annotation.PostConstruct;
import java.util.*;

@Component
@Slf4j
public class WebClientUtil {
    @Autowired
    private ProjProperties projProperties;

    private WebClient webClient;
    private HashMap<String, String> cookiesMap;

    private static final String SESSION_ID = "JSESSIONID";

    private static final HttpClient httpClient = HttpClient.create()
            .secure(t -> t.sslContext(SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)));
//            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
//            .responseTimeout(Duration.ofMillis(60000));

    @PostConstruct
    public void setProperties(){
        webClient =  WebClient.builder()
// 忽略ssl
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .baseUrl(projProperties.getVcm().get("base-url"))
                .build();
    }

    public String request(HttpMethod method, MediaType mediaType, String url){
        return request(method, mediaType,url,null);
    }
    public String request(HttpMethod method, MediaType mediaType, String url, Object data){
        WebClient.RequestBodySpec spec = webClient.method(method)
                .uri(url)
                .contentType(mediaType);
        WebClient.RequestHeadersSpec headersSpec = spec;
        if(!ObjectUtils.isEmpty(cookiesMap)){
            headersSpec = spec.cookie(SESSION_ID, cookiesMap.get(SESSION_ID));
        }
        if(!ObjectUtils.isEmpty(data)){
            headersSpec = spec.body(BodyInserters.fromValue(data));
        }
        Mono<String> mono = headersSpec.exchangeToMono( response -> {
            ClientResponse res = (ClientResponse)response;
            HttpStatus status = res.statusCode();
            List<String> tempCookies = res.headers().header("set-cookie");
            if(!ObjectUtils.isEmpty(tempCookies)){
                String str = tempCookies.get(0);
                String[] arr = str.split(";");
                if(!ObjectUtils.isEmpty(arr)){
                    for (int i = 0; i < arr.length; i++) {
                        String[] sessionArr = arr[i].split("=");
                        if(!ObjectUtils.isEmpty(sessionArr) && sessionArr.length > 1){
                            if(sessionArr[0].equals(SESSION_ID)){
                                cookiesMap = new HashMap<>();
                                cookiesMap.put(sessionArr[0], sessionArr[1]);
                                break;
                            }
                        }
                    }
                }
            }
            if(status.equals(HttpStatus.OK)){
                return res.bodyToMono(String.class);
            } else {
                throw new ArgumentsException(ResultCode.ARGUMENTS_ERROR);
            }
        });
        String responseBody = mono.block();
        return responseBody;
    }
}

三、jackson-dataformat-xml简单使用

编解码函数

package com.sy.ai.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.sy.ai.common.constant.ResultCode;
import com.sy.ai.common.exception.http.HttpException;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Slf4j
public class XmlUtils {
    private static XmlMapper xmlMapper = new XmlMapper();
    public static <T> T deseralize(String str, Class<T> cls){
        InputStream inputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
        T response = null;
        try {
            response = xmlMapper.readValue(inputStream, cls);
        } catch (IOException e) {
            log.error("xml反编码出错");
            e.printStackTrace();
            throw new HttpException(ResultCode.INTERVAL_ERROR);
        }
        return response;
    }
    public static <T> String serialize(T requestObj) {
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
        String req;
        try {
            req = xmlMapper.writeValueAsString(requestObj);
        } catch (JsonProcessingException e) {
            log.error("xml编码出错");
            throw new HttpException(ResultCode.INTERVAL_ERROR);
        }
        return req;
    }
}

Entity编写

// 根元素标签名
@JacksonXmlRootElement(localName = "response")

// 定义节点名称
@JacksonXmlProperty(localName = "result")

// 定义包裹列表的节点名称
@JacksonXmlElementWrapper(localName = "plateList")


//使用时,定义了一个plateList标签包裹的plate节点列表
    @JacksonXmlProperty(localName = "plate")
    @JacksonXmlElementWrapper(localName = "plateList")
    private List<Plate> plateList;
// 忽略空字段的编码与反编码
@JsonInclude(JsonInclude.Include.NON_NULL)

这一步也可以在yaml文件中进行全局配置

spring:
  jackson:
    default-property-inclusion: non_null

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值