XML 来自 API 的响应带有 PathVariable
XML response from API with PathVariable
我有 API:
@GetMapping(path = "/users/{userId}")
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
//logic here
}
它 returns JSON 响应,这是应该的。
还有另一个我无权访问的应用程序,它调用我的 API 作为例如 GET /users/123.xml
以接收 XML 响应。
但在这种情况下,我的 API 失败并出现 400
错误,因为它无法将 123.xml
解析为 Long
。
选项 @GetMapping(value = {"/users/{userId}", "/users/{userId}.xml"})
失败并出现同样的错误。
如何在调用 /{userId}.xml
时用 XML 语法响应,同时在调用 /{userId}
时用 JSON 语法响应?
编辑:
我希望它无需专门添加 'Accept' headers,并且无需编写任何额外的逻辑,它将解析 {userId}.xml
,然后设置适当的响应类型。
我马上想到的最简单的解决方案是有一个可选的请求参数 "responseType",默认值为 json,如果有人想要 XML 响应,他们可以像 :GET /users/123?responseType=xml 这样调用 url
由于参数的默认值将为 'json' 并且它将具有 属性 "required= false",因此在需要 json 响应的用例中您无需担心,并且如果有人想要 XML 响应,他们可以添加可选的 RequestParam。另外,我想你需要为控制器指定 json 和 xml return 类型的产品,让 spring-boot 知道它可以产生不同类型的响应,比如-
@RequestMapping(value = "/users/{userid}", method = RequestMethod.GET,
produces = { MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE)
public ResponseEntity<User> getuserById(@PathVariable String
userid,@RequestParam(required=
false,defaultValue="json",name="responseType"),@RequestHeader ("content-type") String
contentType)
)
编辑:您可以使用请求参数或请求 header,我在示例中提供了两者供您参考
作为 API 的所有者,您应该声明您能够做出什么样的响应 - 在您的情况下,它是 JSON 或 XML:
@GetMapping(path = "/users/{userId}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
return new ResponseEntity<>(userService.get(userId), HttpStatus.OK);
}
API 的任何客户端现在都可以使用 Accept
header 选择首选的响应格式 - 例如 Accept: application/xml
。 Spring 将尊重这一点,并且 return 以请求的格式响应。
要使其正常工作,您需要添加额外的依赖项,Spring 将使用这些依赖项来生成 XML 响应:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
如果你真的需要进入 /users/123.xml
方向,你必须将 userId
类型更改为 String
并像这样自己解析它:
@GetMapping(path = "/users/{userId}")
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") String userId) {
if (hasXMLExtension(userId)) {
return ResponseEntity
.ok()
.contentType(MediaType.XML)
.body(requestdUser);
} else {
return ResponseEntity
.ok()
.contentType(MediaType.JSON)
.body(requestdUser);
}
}
这可以通过使用 ContentNegotiationConfigurer 来完成,您可以按如下方式配置它:
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
}
它应该适用于您的端点:
@GetMapping(path = "/users/{userId}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
return new ResponseEntity<>(userService.get(userId), HttpStatus.OK);
}
我有 API:
@GetMapping(path = "/users/{userId}")
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
//logic here
}
它 returns JSON 响应,这是应该的。
还有另一个我无权访问的应用程序,它调用我的 API 作为例如 GET /users/123.xml
以接收 XML 响应。
但在这种情况下,我的 API 失败并出现 400
错误,因为它无法将 123.xml
解析为 Long
。
选项 @GetMapping(value = {"/users/{userId}", "/users/{userId}.xml"})
失败并出现同样的错误。
如何在调用 /{userId}.xml
时用 XML 语法响应,同时在调用 /{userId}
时用 JSON 语法响应?
编辑:
我希望它无需专门添加 'Accept' headers,并且无需编写任何额外的逻辑,它将解析 {userId}.xml
,然后设置适当的响应类型。
我马上想到的最简单的解决方案是有一个可选的请求参数 "responseType",默认值为 json,如果有人想要 XML 响应,他们可以像 :GET /users/123?responseType=xml 这样调用 url 由于参数的默认值将为 'json' 并且它将具有 属性 "required= false",因此在需要 json 响应的用例中您无需担心,并且如果有人想要 XML 响应,他们可以添加可选的 RequestParam。另外,我想你需要为控制器指定 json 和 xml return 类型的产品,让 spring-boot 知道它可以产生不同类型的响应,比如-
@RequestMapping(value = "/users/{userid}", method = RequestMethod.GET,
produces = { MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE)
public ResponseEntity<User> getuserById(@PathVariable String
userid,@RequestParam(required=
false,defaultValue="json",name="responseType"),@RequestHeader ("content-type") String
contentType)
)
编辑:您可以使用请求参数或请求 header,我在示例中提供了两者供您参考
作为 API 的所有者,您应该声明您能够做出什么样的响应 - 在您的情况下,它是 JSON 或 XML:
@GetMapping(path = "/users/{userId}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
return new ResponseEntity<>(userService.get(userId), HttpStatus.OK);
}
API 的任何客户端现在都可以使用 Accept
header 选择首选的响应格式 - 例如 Accept: application/xml
。 Spring 将尊重这一点,并且 return 以请求的格式响应。
要使其正常工作,您需要添加额外的依赖项,Spring 将使用这些依赖项来生成 XML 响应:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
如果你真的需要进入 /users/123.xml
方向,你必须将 userId
类型更改为 String
并像这样自己解析它:
@GetMapping(path = "/users/{userId}")
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") String userId) {
if (hasXMLExtension(userId)) {
return ResponseEntity
.ok()
.contentType(MediaType.XML)
.body(requestdUser);
} else {
return ResponseEntity
.ok()
.contentType(MediaType.JSON)
.body(requestdUser);
}
}
这可以通过使用 ContentNegotiationConfigurer 来完成,您可以按如下方式配置它:
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
}
它应该适用于您的端点:
@GetMapping(path = "/users/{userId}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<UserDTO> getUserById(@PathVariable(value = "userId") Long userId) {
return new ResponseEntity<>(userService.get(userId), HttpStatus.OK);
}