首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring MVC控制器预处理请求主体

Spring MVC控制器预处理请求主体
EN

Stack Overflow用户
提问于 2013-03-14 04:41:43
回答 4查看 4.8K关注 0票数 1

我正在开发spring REST API。在requirements中,有2个具有相同URL但不同请求体的POST请求。由于Spring MVC必须具有跨控制器的唯一映射,因此我必须对请求正文进行预处理,以映射到特定的POJO。

基于请求体中的session_type,我必须将请求映射到特定的POJO (JSON -> JAVA POJO)。

例如,如果请求体中的'session_type‘是'typeX’,那么请求应该映射到ClassX POJO。如果请求体中的'session_type‘为'typeY’,则请求应映射到ClassY POJO。

有没有办法使用某种requestbody注解呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-03-14 05:07:40

如果你想绑定typeXtypeY,那么你肯定需要两个处理程序。但是,为什么我们不使用@RequestMappingparam选项呢

代码语言:javascript
运行
复制
@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
}

如果您需要一些准备工作(f.e.标准化参数或手动执行模型绑定),那么上面的方法可以与@InitBinder结合使用,但请注意,@InitBinder需要确切的ULR规则以及处理程序中的@ModelAttribute参数。

编辑:在Spring MVC中,不可能使用2个处理程序来处理确切的URL,即当方法/URL/参数/消费类型相同时。

因此,我建议使用统一的处理程序,您可以检查必要的参数,然后手动转换为相应的类。为了找到必要的类,我认为使用Strategy pattern会更好

代码语言:javascript
运行
复制
//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

这种方法不处理验证,并且省略了一些东西,但我相信这可能会有所帮助。

票数 5
EN

Stack Overflow用户

发布于 2013-03-14 04:58:47

我认为您应该为两种类型创建一个方法的控制器,并根据typeXtypeY在其中调用required component\method。

票数 0
EN

Stack Overflow用户

发布于 2013-03-14 05:37:29

GET不应该有请求体,或者至少在它们有请求体的情况下是the server side isn't required to do anything with them。正如您所描述的,此接口不是RESTful。

假设您不关心这一点,请尝试创建一个控制器方法,该方法接受TypeX和TypeY的父类,或者TypeX和TypeY都实现的接口,用@SomethingMeaningfulToYou对其进行注释,然后使用web argument method resolver来实例化您想要的子类。

不过,这是一个破解API的技巧。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15396039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档