This is the 28th day of my participation in the August Text Challenge.More challenges in August
Recently, while writing the JavaEE series, I had some problems writing the SpringMVC rest-style URL. Here is some code.
Index.jsp page code:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"% > <! DOCTYPE html> <html> <head> <meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="springmvc/testRest/1" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="TestRest PUT">
</form>
<br>
<form action="springmvc/testRest/1" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="TestRest DELETE">
</form>
<br>
<form action="springmvc/testRest" method="post">
<input type="submit" value="TestRest POST">
</form>
<br>
<form action="springmvc/testRest/1" method="get">
<input type="submit" value="TestRest GET">
</form>
<br>
</body>
</html>
Copy the code
Controller code:
@RequestMapping("/springmvc")
@Controller
public class RequestMappingTest {
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id) {
System.out.println("testRest PUT:" + id);
return "success";
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable("id") Integer id) {
System.out.println("testRest DELETE:" + id);
return "success";
}
@RequestMapping(value = "/testRest",method = RequestMethod.POST)
public String testRestPost(a) {
System.out.println("testRest POST");
return "success";
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)
public String testRestGet(@PathVariable("id") Integer id) {
System.out.println("testRest GET:" + id);
return "success"; }}Copy the code
Project up and running:
There is no problem with clicking GET or POST, but there is an error with clicking DELETE or PUT.
JSP can only allow GET POST or HEAD.
In fact, I encountered this error a long time ago. When I checked it, there were four ways to solve it:
- Tomcat to version 7.0 and below
- Label the method @responseBody
- The request is forwarded to a Controller and then returned to the JSP page
- Set the isErrorPage property to true in the header of your Success page
At that time, we did solve the problem, but we didn’t go into the exact reason. In recent days, we checked roughly, and many people wrote this mistake on the Internet, but we just gave a solution, and didn’t say why we solved it.
Tomcat to version 7.0 and below
After reviewing a lot of information, I came to the conclusion that the error message was obvious: JSP only allows GET, POST, or HEAD, and when we use the REST style of DELETE and PUT, the error message is obvious.
So why does this not happen when you switch to Tomcat 7.0 or below?
In accordance with the JCP specification (JSP2.3), Tomcat does not support HTTP PUT to access JSP pages from Tomcat8.x. Only GET, POST, and HEAD are supported.
The return value you wrote in the controller method is a string, SpringMVC thinks it’s a JSP page, so it’s an error. This perfectly explains why the first solution works, but switching tomcat versions is clearly not a good idea.
Label the method @responseBody
SpringMVC will treat the return value of the controller method as a JSP page that caused the error, so you can annotate @responseBody on the handler and run the project to try:
It ran successfully, but the return value is displayed on the page.
Here’s how @responseBody works:
The @responseBody annotation converts the return value of a controller method to the specified format through the appropriate converter and writes it to the body area of the Response object, usually to return JSON data or XML data.
Note: After using this annotation, instead of going to the view processor, data is written directly to the input stream, which has the same effect as writing data in the specified format through the Response object.
If you see this, you can see that if you add this annotation, it doesn’t go to the view processor, and of course it doesn’t go to the JSP page, and of course it doesn’t get an error.
However, this annotation is usually used to return data, and if you really want to return data, it’s fine to write this way, and it’s a fairly standard way to write it.
The request is forwarded to a Controller and then returned to the JSP page
If you just want to jump to a JSP page, you can use the third solution. Since you can’t jump directly to the JSP page, you can direct the request to a control method that will then jump to the JSP page. Modify the code of the control class:
@RequestMapping("/springmvc")
@Controller
public class RequestMappingTest {
@RequestMapping("/toSuccess")
public String toSuccess(a) {
System.out.println("toSuccess");
return "success";
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id) {
System.out.println("testRest PUT:" + id);
return "redirect:/springmvc/toSuccess";
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable("id") Integer id) {
System.out.println("testRest DELETE:" + id);
return "redirect:/springmvc/toSuccess";
}
@RequestMapping(value = "/testRest",method = RequestMethod.POST)
public String testRestPost(a) {
System.out.println("testRest POST");
return "success"; }}...Copy the code
In this way, our DELETE and PUT requests do not jump directly to the JSP page, but are first handed over to the toSuccess control method, which jumps to the JSP page.
Set the isErrorPage property to true in the header of your Success page
As for why this solution works, I’m sure you can figure it out for yourself.
If you set the isErrorPage attribute to true in the JSP page to jump to, the error page will be displayed. If you set the isErrorPage attribute to true, the error page will be displayed.
conclusion
All four solutions solve the same problem: JSP does not support DELETE and PUT, so we need to find a way to access JSP without directly accessing them.
However, these methods are always somewhat self-defeating, so use them only when you need to use DELETE and PUT requests, such as to return some data. Otherwise, don’t use them at all.
Teachers often teach us to know what it is and why.