在Spring中结合GET和POST请求方法


70

我有同时支持GETPOST请求的资源。这里是示例资源的示例代码:

@RequestMapping(value = "/books", method = RequestMethod.GET)
public ModelAndView listBooks(@ModelAttribute("booksFilter") BooksFilter filter, two @RequestParam parameters, HttpServletRequest request)
    throws ParseException {
        LONG CODE
}


@RequestMapping(value = "/books", method = RequestMethod.POST)
public ModelAndView listBooksPOST(@ModelAttribute("booksFilter") BooksFilter filter, BindingResult result)
        throws ParseException {
        SAME LONG CODE with a minor difference
}

这两个方法中的代码实际上是相同的,除了可以说一个变量定义。可以使用method = {RequestMethod.POST, RequestMethod.GET}和简单的if内部将两种方法轻松组合。我试过了,但是不起作用,因为这两种方法的末尾都有一个不同的参数,即HttpServletRequestand BindingResult((@RequestParam不需要,因此在POST请求中不需要)。任何想法如何结合这两种方法?


12
为什么不将LONG CODE移至另一种方法?
Narendra Pathai

如果时间太长,您甚至应该将其分成几种简短的方法
JB Nizet

因为我正在寻找更优雅,更通用的解决方案。我认为拥有一个方法booksLogic是我在这两个方法中唯一要调用的方法是不好的。

1
@MilanMilanov:这将是最优雅的解决方案。具有短方法可以很好地完成一件事情并委托其他短方法是您应该努力的目标。
JB Nizet

2
通常,对于不更改服务器的内容,请使用GET;对于不更改服务器的内容,请使用POST。它们是数据库中READ和WRITE的等效http操作。因此,理想的情况是将它们分开并将通用逻辑拆分为其他方法
Dhanush Gopinath

Answers:


102
@RequestMapping(value = "/testonly", method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView listBooksPOST(@ModelAttribute("booksFilter") BooksFilter filter,
        @RequestParam(required = false) String parameter1,
        @RequestParam(required = false) String parameter2, 
        BindingResult result, HttpServletRequest request) 
        throws ParseException {

    LONG CODE and SAME LONG CODE with a minor difference
}

如果这样,@RequestParam(required = true)则必须传递parameter1,parameter2

使用BindingResult并根据您的条件请求它们。

另一种方法

@RequestMapping(value = "/books", method = RequestMethod.GET)
public ModelAndView listBooks(@ModelAttribute("booksFilter") BooksFilter filter,  
    two @RequestParam parameters, HttpServletRequest request) throws ParseException {

    myMethod();

}


@RequestMapping(value = "/books", method = RequestMethod.POST)
public ModelAndView listBooksPOST(@ModelAttribute("booksFilter") BooksFilter filter, 
        BindingResult result) throws ParseException {

    myMethod();

    do here your minor difference
}

private returntype myMethod(){
    LONG CODE
}

5
有什么方法可以找到哪种类型的requestieGETPOSTeg?
Govinda Sakhare'9

您可以检查请求标头。
卡兰

SonarQube发出警报-考虑将此方法范围缩小到一个。
Ashishkel '20

9

下面是实现此目标的一种方法,可能不是理想的方法。

有一种方法可以同时接受两种类型的请求,然后检查您收到的是“ GET”还是“ POST”类型的请求,一旦知道了,就进行相应的操作并调用一种可以完成常见任务的方法都请求方法,即GET和POST。

@RequestMapping(value = "/books")
public ModelAndView listBooks(HttpServletRequest request){
     //handle both get and post request here
     // first check request type and do respective actions needed for get and post.

    if(GET REQUEST){

     //WORK RELATED TO GET

    }else if(POST REQUEST){

      //WORK RELATED TO POST

    }

    commonMethod(param1, param2....);
}

我正在问这个通用方法的签名..它怎么能同时接受HttpServletRequestBindingResult

1
默认情况下,如果您不提及任何映射方法<@RequestMapping(value =“ / books”)>,则它将接受GET和POST请求,只有您需要检查的部分是BindingResult。需要探索。我认为它可以处理仍然需要检查的部分
Jayesh

您可以接受参数内部的HttpServletRequest,此外,如果BindingResult上的数据较少,则可以使用request.getParameter(“ paramName”)接受参数,并根据适用于两者的条件进行检查。(如果BindingResult给您问题,请尝试此操作,否则只有通过删除我认为的RequestMethod映射才能工作)
Jayesh 2013年

1
@RequestMapping(value = "/books", method = { RequestMethod.GET, 
RequestMethod.POST })
public ModelAndView listBooks(@ModelAttribute("booksFilter") BooksFilter filter,
     HttpServletRequest request) 
    throws ParseException {

//your code 
}

这将同时适用于GET和POST。

对于GET,如果您的pojo(BooksFilter)必须包含您在请求参数中使用的属性

像下面

public class BooksFilter{

private String parameter1;
private String parameter2;

   //getters and setters

URl应该如下所示

/ books?parameter1 = blah

这样,您可以将其用于GET和POST

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.