接受具有相同@RequestMapping的两个不同子类

And*_*ose 6 java inheritance spring spring-mvc request-mapping

我有WebDeviceInfoIOSDeviceInfo类,它们是 的子类DeviceInfo。如何在 Spring 中创建一个@RestController接受 或 的IOSDeviceInfo单个端点WebDeviceInfo

尝试#1

我尝试将其映射RequestMapping到两种不同的方法,一种方法是如果可以RequestBody映射到 a则调用WebDeviceInfo,另一种方法如果可以映射RequestBody到 a则调用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
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,第二个方法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");
    }
}
Run Code Online (Sandbox Code Playgroud)

这也行不通。我总是得到:

无法将 deviceInfo 转换为WebDeviceInfoIOSDeviceInfo

尝试#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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我再次收到错误:

无法将 deviceInfo 转换为WebDeviceInfoIOSDeviceInfo

有什么办法可以实现这一点,或者我是否必须使用两个不同的RequestMappings 创建两个单独的方法?

Rom*_*n C 0

您可以使用@PathVariable参数来定义需要反序列化的类型

public void registerDevice(@PathVariable("deviceType") String deviceType, @RequestBody final DeviceInfo deviceInfo) {

switch (deviceType){
...
}
Run Code Online (Sandbox Code Playgroud)