Java系列-SpringBoot-1-入参及出参扩展XML支持
程序员七平Java系列-SpringBoot-1-入参及出参扩展XML支持
前言
现在Java后端项目基本都使用json格式请求和响应数据,因此一般的配置返回json格式数据便能够满足需求。但仍有一些场景需要支持xml格式的请求和响应数据,针对此类需求,
本文在SpringBoot框架上进行配置说明。
注:原spring mvc使用xml配置也支持此配置。
环境
- SpringBoot 版本:2.2.8.RELEASE
相关知识点
Http报头分为通用报头,请求报头,响应报头和实体报头。
请求方的http报头结构:通用报头|请求报头|实体报头
响应方的http报头结构:通用报头|响应报头|实体报头
Accept
:属于请求头,代表发送端(客户端)希望接受的数据类型。
application/xml
,
application/json
;java枚举:MediaType
Content-Type
:代表发送端(客户端|服务器)发送的实体数据的数据类型
application/xml
,
application/json
;java枚举:MediaType
常见的媒体格式类型如下:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
- multipart/form-data : 表单中进行文件上传时使用该格式
以application开头的媒体格式类型:
- application/xhtml+xml :XHTML格式
- application/xml : XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json : JSON数据格式
- application/pdf :pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded :
Spring中consumes和produces的区别
SpringMvc
中如@RequestMapping
之类的注解(@PostMapping
等)有consumes
和produces
这两个属性;
consumes
: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces
: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params
: 指定request中必须包含某些参数值是,才让该方法处理
headers
: 指定request中必须包含某些指定的header值,才能让该方法处理请求
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestController @RequestMapping("/api/v1") public class ApiTestController { @PostMapping(value = "/pay", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) public ApiResponse<TestResponse> testPay(@Validated @RequestBody TestRequest request) { log.info("测试post方法:【{}】", JSON.toJSONString(request)); TestResponse response = TestResponse.builder() .field1("field1") .field2("field2") .field3("field3") .build(); return ApiResponse.ok("请求成功", "1234", "业务成功", response); } }
|
SpringMVC输出格式
在SpringMVC使用ContentNegotiation来判断用户请求希望得到什么格式的数据。
ContentNegotiation 设置了三种方式来设置相应数据的格式,优先级由上至下:
- 通过请求URL后缀:/list.html 返回html格式;
- 通过请求的参数:/list?format=html 该设置默认不开启,默认key是format。
- 通过HTTP Header的Accept:Accept:application/xml
本文在springboot中配置扩展xml格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@Configuration public class ApiMessageConverterConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer .favorPathExtension(true) .favorParameter(true) .parameterName("mediaType") .ignoreAcceptHeader(false) .defaultContentType(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) .mediaType("xml", MediaType.APPLICATION_XML) .mediaType("html", MediaType.TEXT_HTML) .mediaType("json", MediaType.APPLICATION_JSON); } }
|
pom.xml中引入依赖:
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
|
请求实体类配置,需要使用上述依赖中@JacksonXmlRootElement
和@JacksonXmlProperty
注解:
注:xml格式的必须指定根节点;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Data @Builder @NoArgsConstructor @AllArgsConstructor @JacksonXmlRootElement(localName = "request") public class TestRequest extends ApiPayV1Request<TestResponse> implements Serializable { private static final long serialVersionUID = -3135169148798610260L;
@JacksonXmlProperty(localName = "field1") private String field1; private String field2; private String field3;
@Override public Class<TestResponse> getResponseClass() { return TestResponse.class; } }
|
响应实体类配置,同上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| @JacksonXmlRootElement(localName = "root") public class ApiResponse<T> implements Serializable { private static final long serialVersionUID = -3798634638472229369L;
@JacksonXmlProperty(localName = "success") private boolean success;
@JacksonXmlProperty(localName = "code") private String code;
@JacksonXmlProperty(localName = "message") private String message;
@JacksonXmlProperty(localName = "sub_code") private String sub_code;
@JacksonXmlProperty(localName = "sub_msg") private String sub_msg;
@JacksonXmlProperty(localName = "time") @JsonFormat(pattern = "yyyyMMddHHmmssSSS", timezone = "GMT+8") private Timestamp time;
@JacksonXmlProperty(localName = "data") private T data;
@JacksonXmlProperty(localName = "sign") private String sign;
}
|
参考资料