如何禁用OData API的HTTP POST请求?基于Java与ServletRegistrationBean配置
Great question! Let's walk through how to restrict your OData endpoints to accept only GET requests, plus how to implement allow/deny lists for HTTP methods, using your existing ServletRegistrationBean configuration.
1. Where to Configure Request Method Restrictions
You have two clean approaches to enforce this, depending on whether you want to handle it at the servlet container level or OData/JAX-RS layer:
Option 1: Servlet Filter (Container Level)
This is a straightforward way to block unwanted methods before they reach the OData servlet. You can create a custom filter and bind it to your /odata/* path:
First, define the filter:
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ODataMethodRestrictionFilter implements Filter { // Define your allowed methods (white list) private static final String[] ALLOWED_METHODS = {"GET"}; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest) request; HttpServletResponse httpRes = (HttpServletResponse) response; String requestMethod = httpReq.getMethod(); boolean isAllowed = false; for (String method : ALLOWED_METHODS) { if (method.equalsIgnoreCase(requestMethod)) { isAllowed = true; break; } } if (isAllowed) { chain.doFilter(request, response); } else { httpRes.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); httpRes.getWriter().write("HTTP Method " + requestMethod + " is not allowed for OData endpoints"); } } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} }
Then, register this filter alongside your OData servlet registration. You can create a separate FilterRegistrationBean to bind it to the OData path:
// Add this to your existing configuration code FilterRegistrationBean<ODataMethodRestrictionFilter> filterReg = new FilterRegistrationBean<>(); filterReg.setFilter(new ODataMethodRestrictionFilter()); filterReg.addUrlPatterns("/odata/*"); // Ensure this filter runs before the OData servlet filterReg.setOrder(Ordered.HIGHEST_PRECEDENCE); // If using a @Configuration class, return both the servlet and filter registrations
Option 2: JAX-RS Container Request Filter (OData Layer)
Since OData is built on JAX-RS, you can use a ContainerRequestFilter to intercept requests at the OData application level—this gives you tighter integration with OData-specific logic if needed.
First, create the filter:
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import java.io.IOException; @Provider public class ODataMethodValidationFilter implements ContainerRequestFilter { // White list of allowed methods private static final String[] ALLOWED_METHODS = {"GET"}; @Override public void filter(ContainerRequestContext requestContext) throws IOException { String requestMethod = requestContext.getMethod(); boolean isAllowed = false; for (String method : ALLOWED_METHODS) { if (method.equalsIgnoreCase(requestMethod)) { isAllowed = true; break; } } if (!isAllowed) { requestContext.abortWith( Response.status(Response.Status.METHOD_NOT_ALLOWED) .entity("HTTP Method " + requestMethod + " is not allowed for OData endpoints") .build() ); } } }
Next, create a custom subclass of ODataApplication to register this filter (replacing the default OData application you're using):
import org.apache.olingo.odata2.core.rest.app.ODataApplication; import java.util.HashSet; import java.util.Set; public class CustomODataApplication extends ODataApplication { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(super.getClasses()); // Add our custom filter to the OData application classes.add(ODataMethodValidationFilter.class); return classes; } }
Finally, update your ServletRegistrationBean configuration to use this custom application:
ServletRegistrationBean odataServRegstration = new ServletRegistrationBean(new CXFNonSpringJaxrsServlet(), "/odata/*"); Map<String, String> initParameters = new HashMap<>(); // Replace default ODataApplication with your custom implementation initParameters.put("javax.ws.rs.Application", "com.yourpackage.CustomODataApplication"); initParameters.put("org.apache.olingo.odata2.service.factory", "com.sap.context.JPAServiceFactory"); odataServRegstration.setInitParameters(initParameters); return odataServRegstration;
2. White List / Black List Support
Both approaches above can be easily adapted to support either white lists or black lists:
- White List: Define an array of allowed methods (like we did with
ALLOWED_METHODS), and only let requests pass if their method is in the list. - Black List: Define an array of blocked methods (e.g.,
{"POST", "PUT", "DELETE"}), and block requests if their method matches any entry in the list.
For example, a black list version of the filter logic would look like this:
// Black list example private static final String[] BLOCKED_METHODS = {"POST", "PUT", "DELETE", "PATCH"}; // In filter logic: boolean isBlocked = false; for (String method : BLOCKED_METHODS) { if (method.equalsIgnoreCase(requestMethod)) { isBlocked = true; break; } } if (isBlocked) { // Abort the request with 405 status }
内容的提问来源于stack exchange,提问作者JustDeveloper

