2017-05-18 2 views
2

서브 클래스가 DeviceInfoWebDeviceInfoIOSDeviceInfo 클래스가있다. @RestController 봄에 단일 끝점을 만들려면 IOSDeviceInfo 또는 WebDeviceInfo 중 하나를 받아 들일 수 있습니까?@RequestMapping이 동일한 두 개의 다른 서브 클래스를 받아 들인다.

시도 # 1

은 내가 RequestBodyWebDeviceInfo하고 전화를받을 것이라고 다른 매핑 할 수 있다면 전화를받을 것 하나 같은 RequestMapping에 두 가지 방법을지도하려고 한 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 
} 

하지만이 작동하지 않는, 제 2 RequestMapping 등록 및 응용 프로그램은 봄 같은 RequestMethodMediaType/register-device 이미 다른 방법으로 매핑되는 것을 볼 수 있기 때문에 시작되지되지 않습니다.

시도 # 2

다음에, I는 해당 서브 클래스로 캐스팅 한 후 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"); 
    } 
} 

이것은 작동하지 않습니다. 난 항상 얻을 :

Could not cast deviceInfo to WebDeviceInfo or IOSDeviceInfo

을 시도 # 마지막 3

, 난 그냥 try/catch 내부의 정확한 서브 클래스로 캐스팅했습니다.

Could not cast deviceInfo to WebDeviceInfo or IOSDeviceInfo

이러한 목표를 달성하기 위해 어떤 방법이 있나요, 아니면 두 가지 RequestMapping의 두 개의 별도의 방법을 만들어야 할 것입니다 :

@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"); 
     } 
    } 
} 

다시 나는 오류가 얻을?

+0

, 당신은'당신의 httpMssagerConverter을 확장 할 필요가 HTTP 요청, deserialize'하는 'jackson '을 사용하는 경우 매우 쉽습니다. – Jaiwo99

+0

두 번째 및 세 번째 시도에서 Spring MVC가 콘텐츠를'IOSDeviceInfo '또는'WebDeviceInfo '로 역 직렬화하도록 결정하는 방법은 무엇입니까? –

+0

@ Jaiwo99 Spring이 제공하는 기본 설정을 덮어 쓰는 방법에 대한 예가 있습니까? –

답변

0

당신은 당신이 같은 @RequestMapping, 그러나, 당신은 여전히 ​​구별하기 위해 뭔가가 필요 사용할 수 있습니다

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

switch (deviceType){ 
... 
} 
0

를 역 직렬화 할 필요가 입력을 정의하는 매개 변수에 @PathVariable를 사용할 수 있습니다. 마찬가지로, 같은 이름, 경로 및 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){ 

} 

은 그럼 그냥 키 "장치"와 요청에 추가 매개 변수를 추가하고, 봄 올바른 방법을 해결합니다.

예컨대이 원래의 페이로드 (payload) 인 경우 :

{ 
    deviceInfo : {..} 
} 

는 지금이 될 것이다 : 그것은이 방법을 작동하지 않습니다

{ 
    device : "ios", 
    deviceInfo : {..} 
} 
+0

아쉽게도 JSON 페이로드의 값에는 작동하지 않습니다. 여기에있는 '장치'는 POST 된 JSON의 값이 아니라 요청 매개 변수 여야합니다. 이렇게하려면 URL을'/ register-device? device = ios' 또는'/ register-device? device = web'로 바꾸어야합니다. –

관련 문제