retrofit_jackson序列化xml报文

pom.xml

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.3.0</version>
</dependency>

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>converter-jackson</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.5</version>
</dependency>

Api接口

import com.qbsea.mysboot2shirojwt.test.xml.model.RefundRequest;
import com.qbsea.mysboot2shirojwt.test.xml.model.RefundResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface WxPayApi {
	@POST("apitest/custom/response/3.ajax")
	Call<RefundResponse> refund(@Body RefundRequest refund);
}

注入API接口Bean

package com.qbsea.mysboot2shirojwt.test.xml.wxapi;
import com.qbsea.mysboot2shirojwt.test.xml.util.WxPayApiConverterFactory;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import retrofit2.Retrofit;
@Configuration
public class ApiConfig {
	@Bean
	WxPayApi wxPayApi() throws Exception {
		OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
		Retrofit retrofit = new Retrofit.Builder()
				.baseUrl("http://qbsea.com/codeGen/")
				.client(clientBuilder.build())
				.addConverterFactory(new WxPayApiConverterFactory())
				.build();
		return retrofit.create(WxPayApi.class);
	}
}

发送自签名证书

自定义的WxPayApiConverterFactory

1.继承extends Converter.Factory  //import retrofit2.Converter;
2.实现两个转换方法
   @Nullable
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    return null;
}
@Nullable
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    return null;
}
3.实现Converter的两个类 RequestBodyConverter ResponseBodyConverter
 

WxPayApiConverterFactory的具体代码

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
public class WxPayApiConverterFactory extends Converter.Factory  {
	@Nullable
	@Override//请求体的转换 最终返回一个Converter<?, RequestBody>
	public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[]
			methodAnnotations, Retrofit retrofit) {
//		return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
		RequestBodyConverter requestBodyConverter = new RequestBodyConverter<>();
		return requestBodyConverter;
	}
	@Nullable
	@Override//响应体的转换 最终返回一个 Converter<ResponseBody, ?>
		public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
//		return super.responseBodyConverter(type, annotations, retrofit);
		ResponseBodyConverter responseBodyConverter = new ResponseBodyConverter<>(type);
		return responseBodyConverter;
	}
}

RequestBodyConverter转换器

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;
import java.io.IOException;
public class RequestBodyConverter<T> implements Converter<T, RequestBody> {
	private static final MediaType MEDIA_TYPE_XML = MediaType.parse("application/xml; charset=utf-8");
	@Override
	public RequestBody convert(T t) throws IOException {
		XmlMapper xmlMapper = new XmlMapper();
		xmlMapper.registerModule(new JaxbAnnotationModule());
		xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		return RequestBody.create(MEDIA_TYPE_XML, xmlMapper.writeValueAsBytes(t));
	}
}

ResponseBodyConverter

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import lombok.RequiredArgsConstructor;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import java.io.IOException;
import java.lang.reflect.Type;
@RequiredArgsConstructor
public class ResponseBodyConverter<T> implements Converter<ResponseBody,T > {
	private final Type type;
	@Override
	public T convert(ResponseBody responseBody) throws IOException {
		XmlMapper xmlMapper = new XmlMapper();
		xmlMapper.registerModule(new JaxbAnnotationModule());
		xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		return xmlMapper.readValue(responseBody.charStream(),new TypeReference<T>(){
			@Override
			public Type getType() {
				return type;
			}
		});
	}
}

参考的返回报文

<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>
   <sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
   <out_trade_no><![CDATA[1415757673]]></out_trade_no>
   <out_refund_no><![CDATA[1415701182]]></out_refund_no>
   <refund_id><![CDATA[2008450740201411110000174436]]></refund_id>
   <refund_fee>1</refund_fee>
</xml>

Mode类参考

请求RefundRequest


import lombok.Getter;
import lombok.Setter;

import javax.xml.bind.annotation.XmlElement;

@Getter
@Setter
public class RefundRequest extends WxPayRequest {

	@XmlElement(name = "transaction_id")
	private String flowNo;

	@XmlElement(name = "out_refund_no")
	private String refundTradeNo;

	@XmlElement(name = "total_fee")
	private int totalFee;

	@XmlElement(name = "refund_fee")
	private int refundFee;

	@XmlElement(name = "refund_desc")
	private String refundReason;

}

请求WxPayRequest 

import lombok.Getter;
import lombok.Setter;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@Getter
@Setter
@XmlRootElement(name = "xml")
public abstract class WxPayRequest implements Serializable {
	@XmlElement(name = "appid")
	private String appId;
	@XmlElement(name = "mch_id")
	private String mchId;
	@XmlElement(name = "nonce_str")
	private String nonce;
	@XmlElement(name = "sign")
	private String signature;
	@XmlElement(name = "sign_type")
	private String signType = "HMAC-SHA256";
}

响应RefundResponse

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlElement;
@Getter
@Setter
@ToString
public class RefundResponse extends WxPayResponse {

	@XmlElement(name = "result_code")
	private String resultCode;

	@XmlElement(name = "err_code")
	private String errorCode;

	@XmlElement(name = "err_code_des")
	private String errorDesc;

	@XmlElement(name = "out_refund_no")
	private String refundTradeNo;

	@XmlElement(name = "refund_id")
	private String refundFlowNo;

	public boolean isSuccessful() {
		return SUCCESS_CODE.equals(getCode()) && SUCCESS_CODE.equalsIgnoreCase(getResultCode());
	}

}

响应WxPayResponse 


import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import lombok.Getter;
import lombok.Setter;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@Getter
@Setter
@XmlRootElement(name = "xml")
public class WxPayResponse implements Serializable {

	public static final String SUCCESS_CODE = "SUCCESS";
	public static final String FAILURE_CODE = "FAIL";

	@XmlElement(name = "return_code")
	@JacksonXmlCData
	private String code;

	@XmlElement(name = "return_msg")
	@JacksonXmlCData
	private String message;

	public static WxPayResponse success() {
		WxPayResponse response = new WxPayResponse();
		response.setCode(SUCCESS_CODE);
		response.setMessage("OK");
		return response;
	}

	public static WxPayResponse failure(String message) {
		WxPayResponse response = new WxPayResponse();
		response.setCode(SUCCESS_CODE);
		response.setMessage(message);
		return response;
	}

}


 

猜你喜欢

转载自blog.csdn.net/maqingbin8888/article/details/83541152