简体   繁体   English

Spring MVC Controller预处理请求正文

[英]Spring MVC Controller pre process request body

I am working on spring REST APIs. 我正在研究Spring REST API。 In requirements, there are 2 POST requests with same URL but different request body. 在需求中,有2个POST请求具有相同的URL,但请求主体不同。 Since Spring MVC must have unique mappings across controller, I have to pre-process the request body to map to a specific POJO. 由于Spring MVC必须跨控制器具有唯一的映射,因此我必须预处理请求主体以映射到特定的POJO。

On the basis of session_type in request body, I have to map the request to specific POJO (JSON -> JAVA POJO). 根据请求正文中的session_type,我必须将请求映射到特定的POJO(JSON-> JAVA POJO)。

For example, if 'session_type' in request body is 'typeX' then the request should map to ClassX POJO. 例如,如果请求正文中的“ session_type”为“ typeX”,则请求应映射到ClassX POJO。 If 'session_type' in request body is 'typeY' then the request should map to ClassY POJO. 如果请求正文中的“ session_type”为“ typeY”,则请求应映射到ClassY POJO。

If there a way to do it using some kind of requestbody annotation? 是否可以使用某种requestbody注释来做到这一点?

If you want to bind typeX and typeY , then you definitely need 2 handlers. 如果要绑定typeXtypeY ,则肯定需要2个处理程序。 But, why wouldn't we use param option of @RequestMapping : 但是,为什么我们不使用@RequestMapping param选项:

@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
}

If you need some preparations (fe normalize params or perform model binding manually), then the approach above you may combine along with @InitBinder , but please note, that @InitBinder needs exact ULR's rules along with @ModelAttribute parameters in handlers. 如果您需要一些准备工作(例如,规范化参数或手动执行模型绑定),则可以将上述方法与@InitBinder结合使用,但请注意, @InitBinder需要确切的@InitBinder规则以及处理程序中的@ModelAttribute参数。

EDIT : In Spring MVC there is no possibility to use 2 handlers for exact URL , ie when method/URL/params/consumes type are the same. 编辑 :在Spring MVC中,不可能使用2个用于确切URL的处理程序,即,当method / URL / params / consumes类型相同时。

Thus I suggest use unified handler, where you would check necessary parameter and then manually convert into corresponding class. 因此,我建议使用统一处理程序,在该程序中您将检查必要的参数,然后手动将其转换为相应的类。 For finding necessary class I suppose it would be better to use Strategy pattern : 为了找到必要的课程,我想最好使用Strategy模式

//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

This approach doesn't handle validation and some things were omitted, but I believe this might be helpful. 这种方法无法处理验证,因此省略了一些内容,但我认为这可能会有所帮助。

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

GETs shouldn't have request bodies, or at least if they do, the server side isn't required to do anything with them . GET不应具有请求主体,或者至少具有请求主体, 服务器端无需对其进行任何处理 As you describe it, this API isn't RESTful. 正如您描述的那样,该API不是RESTful的。

Assuming you don't care about that, try creating a controller method that takes a parent class of TypeX and TypeY, or interface that both TypeX and TypeY implement, annotate it with @SomethingMeaningfulToYou, then use a web argument method resolver to instantiate the child class you want. 假设您对此不关心,请尝试创建一个采用TypeX和TypeY父类的控制器方法,或者使用TypeX和TypeY都实现的接口,然后使用@SomethingMeaningfulToYou对其进行注释,然后使用网络参数方法解析器实例化该子级。你想要的课。

It's a hack around a broken API though. 不过,这是围绕损坏的API的黑客。

there are 2 POST requests with same URL but different request body 有2个POST请求具有相同的URL,但请求正文不同

For a RESTful interface, the same URL should always indicate the same resource . 对于RESTful接口,相同的URL应始终指示相同的资源 The body of a request may contain different representations of that resource. 请求的正文可能包含该资源的不同表示形式 You could create different HttpMessageContverter classes for the two different kinds of representation. 您可以为两种不同的表示形式创建不同的HttpMessageContverter类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在将请求主体传递给Controller之前,该如何在Spring中对其进行预处理? - How to pre-process the request body in Spring before passing it to the a Controller? Spring控制器预处理@ModelAttribute请求参数 - Spring controller pre-process @ModelAttribute request parameters Spring MVC:如何在请求浏览器中设置主体参数,以及如何在Spring MVC的控制器中获取该主体参数? - Spring MVC: How to set body parameter in request browser and how to get this body parameters in controller in Spring MVC? 如何在 Spring 控制器中请求请求的来源和正文 - How to request origin and body of a request in Spring controller Spring MVC:请求正文中的JSONObject请求映射 - Spring MVC: Request Mapping for JSONObject in Request body Spring MVC控制器返回请求 - Spring MVC controller returns request 如何将请求发送到另一个域并在Spring MVC控制器中获取响应正文? - How do I send a request to another domain and get the response body in a Spring MVC controller? 无法将JSON作为请求正文发送到Spring Controller - Cannot send JSON as request body to Spring Controller Spring Controller-记录请求和响应主体 - Spring controller - logging request and response body Java Spring REST控制器:请求主体不完整 - Java spring REST controller: incomplete request body
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM