0
votes

I have a project based in Spring Web model-view-controller (MVC) framework. The version of the Spring Web model-view-controller (MVC) framework is 3.2.8

I have this controller

@SuppressWarnings("unchecked")
    @RequestMapping(value = { "/books/store/product",
                  "/books/store/product/",
                  "/books/store/product/{productId}",
                  "/books/store/product/{productId}/" }, method = { RequestMethod.POST })
    public String saveProduct(@ModelAttribute("productForm") ProductForm productForm, 
                              @PathVariable Long productId,
            HttpServletRequest request, Model model) throws Exception {

..
}

Everything is fine for this URL : /books/store/product/232

but for this one /books/store/product/

I got this error:

Error 400--Bad Request

From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:

10.4.1 400 Bad Request

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

I've tried to put this @PathVariable(required = false), but I got a compilation error: The attribute required is undefined for the annotation type PathVariable

2
You should add @PathVariable(required=false) - zakaria amine
it's better to separate it into two methods one with PathVariable and the other without, also no need to add "/" mappings, it's useless - zakaria amine

2 Answers

1
votes

This is because the service is always waiting for the path variable productId

Because you're using Spring 3 I suggest you to create 2 methods. One with the path variable and the other without it.

 @RequestMapping(value = { "/books/store/product",
                  "/books/store/product/"}, method = { RequestMethod.POST })
    public String saveProduct(@ModelAttribute("productForm") ProductForm productForm,
            HttpServletRequest request, Model model) throws Exception {

..
}

 @RequestMapping(value = { "/books/store/product/{productId}",
                  "/books/store/product/{productId}/" }, method = { RequestMethod.POST })
    public String saveProduct(@ModelAttribute("productForm") ProductForm productForm, 
                              @PathVariable Long productId,
            HttpServletRequest request, Model model) throws Exception {

..
}

If you're using Spring 4 and Java 8 I suggest you to use optional.

@PathVariable Optional<Long> productId
0
votes

If you do not always need productId. Try using query parameter and make it optional. required=false

This url will now look like:

  1. http://localhost:8080/books/store/product?productId=232
  2. http://localhost:8080/books/store/product

Like this:

@SuppressWarnings("unchecked")
    @RequestMapping(value = { "/books/store/product",
                   }, method = { RequestMethod.POST })
    public String saveProduct(@ModelAttribute("productForm") ProductForm productForm,
 @RequestParam(value = "productId", required = false) Long productId,
            HttpServletRequest request, Model model) throws Exception {

..
}

Hope it helps.