gpt4 book ai didi

java - SpringBoot : Consume & Produce XML with a Custom Serializer + Deserializer

转载 作者:行者123 更新时间:2023-11-30 05:27:55 25 4
gpt4 key购买 nike

我有一个 SpringBoot 服务:

型号

public class Payload {
private final String id;

public Payload(String id){
this.id = id;
}

public String getId() {
return this.id;
}
}

Controller

@RestController
@RequestMapping("/payload")
public class PayloadController {

@RequestMapping(method = RequestMethod.POST)
public Payload post(@RequestBody final Payload payload) {
return payload;
}
}

我需要这个 Controller 能够处理 JSON 和 XML 请求并以相同的格式响应。如果我将 Content-TypeAccept header 设置为正确的媒体类型,则效果很好。

但是,我的 XML 有效负载需要采用与 JSON 略有不同的结构:

XML:

<Payload>
<id value="some-value"/>
</Payload>

JSON:

{
id: "some-value"
}

如何确保我的 id 包装在 xml 节点中并具有“值”作为属性?

<小时/>

我尝试在我的 Payload 类上使用 @JsonSerialize@JsonDeserialize 注释,但一旦我这样做,我就会得到以下结果POST处理 XML 时出错

{
"timestamp": "2019-10-01T12:06:35.593+0000",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'application/xml;charset=UTF-8' not supported",
"path": "/payload"
}

最佳答案

您需要注册2个转换器:

  1. org.springframework.http.converter.json.MappingJackson2HttpMessageConverter 用于 JSON
  2. org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter 用于XML

因为 Payload 类适合 JSON 有效负载,因此您只需添加 JsonCreatorJsonProperty 注释即可使其生效工作:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Payload {

private final String id;

@JsonCreator
public Payload(@JsonProperty(value = "id") String id) {
this.id = id;
}

public String getId() {
return this.id;
}
}

XML 负载默认不适合,因此我们需要实现自定义序列化程序:

import com.example.demo.model.Payload;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;

import java.io.IOException;

public class PayloadXmlSerializer extends JsonSerializer<Payload> {

@Override
public void serialize(Payload value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
ToXmlGenerator toXmlGenerator = (ToXmlGenerator) gen;
toXmlGenerator.writeStartObject();

toXmlGenerator.writeObjectFieldStart("id");
toXmlGenerator.setNextIsAttribute(true);
toXmlGenerator.writeFieldName("value");
toXmlGenerator.writeString(value.getId());
toXmlGenerator.setNextIsAttribute(false);
toXmlGenerator.writeEndObject();

toXmlGenerator.writeEndObject();
}
}

和解串器:

import com.example.demo.model.Payload;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.node.TextNode;

import java.io.IOException;

public class PayloadXmlDeserializer extends JsonDeserializer<Payload> {

@Override
public Payload deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
TreeNode root = p.readValueAsTree();
TreeNode value = root.at(JsonPointer.compile("/id/value"));
if (value.isMissingNode()) {
return new Payload(null);
}
TextNode textNode = (TextNode)value;
return new Payload(textNode.textValue());
}
}

最后,我们需要注册上述 HTTP 转换器和自定义序列化器/反序列化器:

import com.example.demo.model.Payload;
import com.example.jackson.PayloadXmlDeserializer;
import com.example.jackson.PayloadXmlSerializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//JSON
converters.add(new MappingJackson2HttpMessageConverter());

// XML
converters.add(new MappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder
.xml()
.modules(payloadModule())
.build()));
}

public SimpleModule payloadModule() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Payload.class, new PayloadXmlDeserializer());
module.addSerializer(Payload.class, new PayloadXmlSerializer());

return module;
}
}

另请参阅:

关于java - SpringBoot : Consume & Produce XML with a Custom Serializer + Deserializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58184442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com