gpt4 book ai didi

java - 如何根据条件创建 xml webservice DTO?

转载 作者:行者123 更新时间:2023-11-30 07:16:13 25 4
gpt4 key购买 nike

是否可以为 xml Web 服务创建全局 DTO,但内部包含条件字段?

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MyDTO {
...
@XmlElementWrapper
@XmlElement(name = "somename")
private List<String> list;
}

现在,如果我想发布另一个版本的 Web 服务,并重命名 @XmlElement 字段(或引入其他字段、删除一些字段等),该怎么办?

这样就保留了向后兼容性,但"new"版本使用相同的对象。

我也许可以使用 /v1/v2 等添加请求路径方法。但是我怎样才能维护一个 DTO 类,但字段以版本路径为条件呢?

或者我是否总是必须复制这些 DTO 类并完全根据我的版本需求进行修改?

@RestController
public void MyServlet {
@RequestMapping("/v1")
public MyDTO1 request1() {

}

@RequestMapping("/v2")
public MyDTO2 request2() {

}
}

最佳答案

我更喜欢为每个版本的 API 使用定制的 DTO。为了避免在将实体映射到 DTO 时出现样板代码,您可以考虑使用映射框架,例如 MapStruct .

如果您使用 Jackson,您可以考虑使用 JSON View (它们也可以使用 XML)。引用自 Latest Jackson integration improvements in Spring文章:

JSON Views

It can sometimes be useful to filter contextually objects serialized to the HTTP response body. In order to provide such capabilities, Spring MVC now has builtin support for Jackson’s Serialization Views (as of Spring Framework 4.2, JSON Views are supported on @MessageMapping handler methods as well).

The following example illustrates how to use @JsonView to filter fields depending on the context of serialization - e.g. getting a “summary” view when dealing with collections, and getting a full representation when dealing with a single resource:

public class View {
interface Summary {}
}
public class User {

@JsonView(View.Summary.class)
private Long id;

@JsonView(View.Summary.class)
private String firstname;

@JsonView(View.Summary.class)
private String lastname;

private String email;
private String address;
private String postalCode;
private String city;
private String country;
}
public class Message {

@JsonView(View.Summary.class)
private Long id;

@JsonView(View.Summary.class)
private LocalDate created;

@JsonView(View.Summary.class)
private String title;

@JsonView(View.Summary.class)
private User author;

private List<User> recipients;

private String body;
}

Thanks to Spring MVC @JsonView support, it is possible to choose, on a per handler method basis, which field should be serialized:

@RestController
public class MessageController {

@Autowired
private MessageService messageService;

@JsonView(View.Summary.class)
@RequestMapping("/")
public List<Message> getAllMessages() {
return messageService.getAll();
}

@RequestMapping("/{id}")
public Message getMessage(@PathVariable Long id) {
return messageService.get(id);
}
}

In this example, if all messages are retrieved, only the most important fields are serialized thanks to the getAllMessages() method annotated with @JsonView(View.Summary.class):

[ {
"id" : 1,
"created" : "2014-11-14",
"title" : "Info",
"author" : {
"id" : 1,
"firstname" : "Brian",
"lastname" : "Clozel"
}
}, {
"id" : 2,
"created" : "2014-11-14",
"title" : "Warning",
"author" : {
"id" : 2,
"firstname" : "Stéphane",
"lastname" : "Nicoll"
}
}, {
"id" : 3,
"created" : "2014-11-14",
"title" : "Alert",
"author" : {
"id" : 3,
"firstname" : "Rossen",
"lastname" : "Stoyanchev"
}
} ]

In Spring MVC default configuration, MapperFeature.DEFAULT_VIEW_INCLUSION is set to false. That means that when enabling a JSON View, non annotated fields or properties like body or recipients are not serialized.

When a specific Message is retrieved using the getMessage() handler method (no JSON View specified), all fields are serialized as expected:

{
"id" : 1,
"created" : "2014-11-14",
"title" : "Info",
"body" : "This is an information message",
"author" : {
"id" : 1,
"firstname" : "Brian",
"lastname" : "Clozel",
"email" : "bclozel@pivotal.io",
"address" : "1 Jaures street",
"postalCode" : "69003",
"city" : "Lyon",
"country" : "France"
},
"recipients" : [ {
"id" : 2,
"firstname" : "Stéphane",
"lastname" : "Nicoll",
"email" : "snicoll@pivotal.io",
"address" : "42 Obama street",
"postalCode" : "1000",
"city" : "Brussel",
"country" : "Belgium"
}, {
"id" : 3,
"firstname" : "Rossen",
"lastname" : "Stoyanchev",
"email" : "rstoyanchev@pivotal.io",
"address" : "3 Warren street",
"postalCode" : "10011",
"city" : "New York",
"country" : "USA"
} ]
}

Only one class or interface can be specified with the @JsonView annotation, but you can use inheritance to represent JSON View hierarchies (if a field is part of a JSON View, it will be also part of parent view). For example, this handler method will serialize fields annotated with @JsonView(View.Summary.class) and @JsonView(View.SummaryWithRecipients.class):

public class View {
interface Summary {}
interface SummaryWithRecipients extends Summary {}
}
public class Message {

@JsonView(View.Summary.class)
private Long id;

@JsonView(View.Summary.class)
private LocalDate created;

@JsonView(View.Summary.class)
private String title;

@JsonView(View.Summary.class)
private User author;

@JsonView(View.SummaryWithRecipients.class)
private List<User> recipients;

private String body;
}
@RestController
public class MessageController {

@Autowired
private MessageService messageService;

@JsonView(View.SummaryWithRecipients.class)
@RequestMapping("/with-recipients")
public List<Message> getAllMessagesWithRecipients() {
return messageService.getAll();
}
}

关于java - 如何根据条件创建 xml webservice DTO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38370152/

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