如果你想绑定typeX
and typeY
,那么你肯定需要 2 个处理程序。但是,我们为什么不使用以下param
选项@RequestMapping
:
@RequestMapping(method = RequestMethod.POST,
value = "/url", params = "session_type=typeX")
public String handleTypeX(@RequestBody @ModelAttribute TypeX typeX){
//TODO implement
}
@RequestMapping(method = RequestMethod.POST,
value = "/url", params = "session_type=typeY")
public String handleTypeY(@RequestBody @ModelAttribute TypeY typeY){
//TODO implement
}
如果您需要一些准备工作(fe 规范化参数或手动执行模型绑定),那么您可以将上述方法与 结合使用@InitBinder
,但请注意,这@InitBinder
需要精确的 ULR 规则以及@ModelAttribute
处理程序中的参数。
编辑:在 Spring MVC 中,不可能对确切的 URL使用 2 个处理程序,即当 method/URL/params/consumes 类型相同时。
因此我建议使用统一处理程序,您可以在其中检查必要的参数,然后手动转换为相应的类。为了找到必要的课程,我认为使用策略模式会更好:
//class resolver according "session_type" parameter
//note, that you can use Spring autowiring capabilities
private final Map<String, Class> TYPES_CONTEXT = new HashMap<String, Class>(){
{
this.put("x", TypeX.class);
this.put("y", TypeY.class);
//TODO probably other classes
}
}
@RequestMapping(method = RequestMethod.POST,
value = "/url")
public @ResponseBody String handleAnyType(@RequestBody Map<String, String> body){
String sessionType = body.get("session_type");
//TODO handle case if sessionType is NULL
Class convertedClass = TYPES_CONTEXT.get(sessionType);
//TODO handle case if class is not found
Object actualObject = objectMapper.convertValue(body, convertedClass);
//now we use reflection for actual handlers, but you may refactor this in the way you want, f.e. again with Strategy pattern
//note that current approach there should be contract for methods names
Method actualHandler = this.getClass().getMethod("handle" + actualObject.getClass().getSimpleName());
return (String)actualHandler.invoke(this, actualObject);
}
public String handleTypeX(TypeX typeX){
//TODO implement
}
public String handleTypeY(TypeY typeY){
//TODO implement
}
//TODO probably other methods
这种方法不处理验证,有些东西被省略了,但我相信这可能会有所帮助。