我有WebDeviceInfo
和IOSDeviceInfo
个类,它们是DeviceInfo
的子类。如何在弹簧@RestController
中创建一个接受IOSDeviceInfo
或WebDeviceInfo
的单个端点?
尝试#1
我尝试将同一个RequestMapping
映射到两个不同的方法,如果RequestBody
可以映射到WebDeviceInfo
,另一个会被调用,另一个会被调用RequestBody
可以映射到IOSDeviceInfo
。
@RequestMapping(value = "/register-device", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void registerWebDevice(@RequestBody final WebDeviceInfo webDeviceInfo) {
//register web device
}
@RequestMapping(value = "/register-device", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void registerIOSDevice(@RequestBody final IOSDeviceInfo iosDeviceInfo) {
//register ios device
}
但是这不起作用,第二个RequestMapping
没有注册,应用程序无法启动,因为Spring看到/register-device
具有相同的RequestMethod
和MediaType
已经映射到另一种方法。
尝试#2
接下来,我尝试接受超类作为RequestBody
,然后将其转换为适当的子类。
@RequestMapping(value = "/register-device", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void registerDevice(@RequestBody final DeviceInfo deviceInfo) {
if (deviceInfo instanceof WebDeviceInfo) {
final WebDeviceInfo webDeviceInfo = (WebDeviceInfo) deviceInfo;
//register web device
} else if (deviceInfo instanceof IOSDeviceInfo) {
final IOSDeviceInfo iosDeviceInfo = (IOSDeviceInfo) deviceInfo;
//register ios device
} else {
logger.debug("Could not cast deviceInfo to WebDeviceInfo or IOSDeviceInfo");
}
}
这也不起作用。我总是得到:
无法将deviceInfo强制转换为WebDeviceInfo或IOSDeviceInfo
尝试#3
最后,我尝试在try
/ catch
内投射到正确的子类。
@RequestMapping(value = "/register-device", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void registerDevice(@RequestBody final DeviceInfo deviceInfo) {
try {
final WebDeviceInfo webDeviceInfo = (WebDeviceInfo) deviceInfo);
//register web device
} catch (final ClassCastException ex) {
try {
final IOSDeviceInfo iosDeviceInfo = (IOSDeviceInfo) deviceInfo);
//register ios device
} catch (final ClassCastException ex2) {
logger.debug("Could not cast deviceInfo to WebDeviceInfo or IOSDeviceInfo");
}
}
}
我再次收到错误:
无法将deviceInfo强制转换为WebDeviceInfo或IOSDeviceInfo
有没有办法实现这一点,或者我将不得不用两个不同的RequestMapping
创建两个单独的方法?
答案 0 :(得分:0)
您可以使用@PathVariable
参数来定义反序列化所需的类型
public void registerDevice(@PathVariable("deviceType") String deviceType, @RequestBody final DeviceInfo deviceInfo) {
switch (deviceType){
...
}
答案 1 :(得分:0)
您可以使用相同的@RequestMapping
,但是,您仍然需要一些东西来区分它们。同样,我的意思是相同的名称,路径和RequestMethod。
您可以在请求映射中使用params
参数来区分它们。
例如,
@RequestMapping(value = "/register-device",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
params="device=android")
public void registerDevice(@RequestBody final WebDeviceInfo deviceInfo){
}
@RequestMapping(value = "/register-device",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
params="device=ios")
public void registerDevice(@RequestBody final IOSDeviceInfo deviceInfo){
}
然后只需使用键“device”向请求添加一个额外的参数,Spring将解析正确的方法。
例如,如果这是你原来的有效载荷:{
deviceInfo : {..}
}
现在就是这样:
{
device : "ios",
deviceInfo : {..}
}