There is a problem that PUT and DELETE methods cannot be used when running JSP on Tomcat 8 or later.
https://stackoverflow.com/questions/23886941/http-status-405-jsps-only-permit-get-post-or-head
Due to this limitation, when you make a request to a JSP with the PUT or DELETE method, 405 Method Not Allowed is returned. Since it is blocked at the container level, changing the processing and settings of the Servlet has no effect.
This issue can be overcome with HTTP method overrides. However, allowing PUT and DELETE may cause security problems, so please judge the application of this method at your own risk.
It's easy to do, just add x-http-method to the header and access with the POST method.
curl -X POST -H "Content-Type:application/json" -H "x-http-method:PUT" -d "<data>" "<API URL>"
However, some HTTP clients may not have the function to rewrite the header. In that case, you can handle it by adding the following servlet filter on the server side.
The Servlet filter is a mechanism that allows processing to be inserted between the Servlet container and the Servlet, and can perform pre-processing of requests for Web applications and post-processing of responses.
It implements the HTTP method override described above. This allows the container to accept PUT or DELETE as POST and pass it to the Servlet as PUT or DELETE.
Below is the sample source code of the filter that executes the HTTP method override.
package test;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MethodConvertingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// do nothing
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(wrapRequest((HttpServletRequest) request), response);
}
@Override
public void destroy() {
// do nothing
}
private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) {
return new HttpServletRequestWrapper(request) {
@Override
public String getMethod() {
//Returns that this request is POST if the request method is PUT or DELETE
if(request.getMethod().equalsIgnoreCase("PUT") || request.getMethod().equalsIgnoreCase("DELETE")) {
return "POST";
}
return request.getMethod();
}
@Override
public String getHeader(String name) {
// x-http-Set the original method in the method header
if(name.equalsIgnoreCase("x-http-method")) {
return request.getMethod();
}
return super.getHeader(name);
}
@Override
public Enumeration getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
// x-http-Added method header
names.add("x-http-method");
return Collections.enumeration(names);
}
};
}
}
Compile the filter source and place the generated class files in your web application's WEB-INF/classes.
Add the following filter definition to web.xml. If multiple filters are defined, the processing will be applied in the defined order, so pay attention to the definition position.
<filter>
<filter-name>MethodConvertingFilter</filter-name>
<filter-class>test.MethodConvertingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MethodConvertingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
This completes the implementation. You will be able to perform PUT and DELETE normally.
Recommended Posts