This tutorial shows how to handle HTTP PUT request in Spring MVC
According to Spring reference document:
Browsers can submit form data only through HTTP GET or HTTP POST but non-browser clients can also use HTTP PUT, PATCH, and DELETE. The Servlet API requires ServletRequest.getParameter*() methods to support form field access only for HTTP POST.
The spring-web module provides
FormContentFilter to intercept HTTP PUT, PATCH, and DELETE requests with a content type of application/x-www-form-urlencoded, read the form data from the body of the request, and wrap the ServletRequest to make the form data available through the ServletRequest.getParameter*() family of methods.
FormContentFilter FormContentFilter has been available since Spring 5.1. Before that, HttpPutFormContentFilter was used for the same purpose, but it was deprecated in 5.1 in favor of FormContentFilter.
In the following example, we will submit the PUT request from JQuery and instead of using ServletRequest we will use @RequestBody MultiValueMap to access the form parameter.
Example
The controller
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/articles")
public class ArticleController {
@Autowired
private ArticleService articleService;
@GetMapping
public String getArticleForm() {
return "article-form";
}
@PutMapping(value = "/{id}")
@ResponseBody
public String createNewArticle(@RequestBody
MultiValueMap<String, String> formParams) {
System.out.println(formParams);
long id = Long.parseLong(formParams.getFirst("id"));
String content = formParams.getFirst("content");
Article article = new Article(id, content);
articleService.saveArticle(article);
return "Article created.";
}
@GetMapping(value = "/{id}")
public String getArticle(@PathVariable("id") long id,
Model model) {
Article article = articleService.getArticleById(id);
model.addAttribute("article", article);
return "article-page";
}
}
package com.logicbig.example;
public class Article {
private long id;
private String content;
public Article(long id,
String content) {
this.id = id;
this.content = content;
}
.............
}
src/main/webapp/WEB-INF/views/article-form.jsp<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
<body>
<h3>Article Form</h3>
<form id="article-form">
<pre>
id: <input type="text" name="id">
content: <input type="text" name="content">
<input type="submit" value="Submit">
</pre>
</form>
<br/>
<div id="result"></div>
<script>
$("#article-form").submit(function(event){
event.preventDefault();
var form = $(this);
var id = form.find('input[name="id"]').val();
var url = 'http://localhost:8080/articles/'+id;
var content = form.find('input[name="content"]').val();
$.ajax({
type : 'PUT',
url : url,
contentType: 'application/x-www-form-urlencoded',
data : "id="+id+"&content="+content,
success : function(data, status, xhr){
$("#result").html(data+
" link: <a href='"+url+"'>"+url+"</a>");
},
error: function(xhr, status, error){
alert(error);
}
});
});
</script>
</body>
</html>
src/main/webapp/WEB-INF/views/article-page.jsp<html>
<body>
<h3>Article</h3>
${article}
</form>
</body>
</html>
Java Config
package com.logicbig.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
}
Running Example
To try examples, run embedded Jetty (configured in pom.xml of example project below):
mvn jetty:run
Accessing http://localhost:8080/articles and filling up the form:
On submitting the form:
Clicking on the hyper link of the article:
Using curl
$ curl -s -X PUT "http://localhost:8080/articles/1" -d "id=1&content=test" Article created.
$ curl -s "http://localhost:8080/articles/1" <html> <body> <h3>Article</h3> Article{id=1, content='test'} </form> </body> </html>
See also Servlet - doPut() Example.
Example ProjectDependencies and Technologies Used: - spring-webmvc 7.0.6 (Spring Web MVC)
Version Compatibility: 3.2.9.RELEASE - 7.0.6 Version compatibilities of spring-webmvc with this example: Versions in green have been tested.
- spring-test 7.0.6 (Spring TestContext Framework)
- jakarta.servlet-api 6.1.0 (Jakarta Servlet API documentation)
- jakarta.servlet.jsp.jstl 3.0.1 (Jakarta Standard Tag Library Implementation)
- JDK 25
- Maven 3.9.11
|