Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No resource method found for options, return OK with Allow header: org.jboss.resteasy.spi.DefaultOptionsMethodException

I am trying to make a post request from my Ionic 3 application to a Java resource but it bursts that error that is in the title, below is the method for which I am making the request:

@POST
@Path("/loginCpf")
@Produces(MediaType.APPLICATION_JSON)
public Integer validarBeneficiarioCpf(BeneficiarioLoginTO beneficiario) throws Exception, TypeWarnWebException {
    HttpSession session = (HttpSession) request.getSession(true);
    Integer numOpcoes = beneficiarioLoginNegocio.validarCpfLogin(beneficiario);
    if(session.getAttribute("beneficiario") == null && numOpcoes == null){
        return -1;
    }
    return numOpcoes;
}

and the error that throws:

09:32:0 3,649 ERROR [br.gov.transportes.spl.web.exception.provider.ExceptionResourceMapper] (http--0.0.0.0-443-3) No resource method found for options, return OK with Allow header: org.jboss.resteasy.spi.DefaultOptionsMethodException: No resource method found for options, return OK with Allow header
        at org.jboss.resteasy.core.registry.Segment.match(Segment.java:107) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.SimpleSegment.matchSimple(SimpleSegment.java:33) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.RootSegment.matchChildren(RootSegment.java:327) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.SimpleSegment.matchSimple(SimpleSegment.java:44) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.RootSegment.matchChildren(RootSegment.java:327) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.RootSegment.matchRoot(RootSegment.java:374) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.registry.RootSegment.matchRoot(RootSegment.java:367) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:307) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:173) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:118) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.2.Final.jar:]
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.2.Final.jar:]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at br.gov.transportes.spl.web.filter.CacheFilter.doFilter(CacheFilter.java:36) [classes:]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
        at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_79]

This is my Ionic 2 request method:

  getUser() {
     return new Promise((resolve, reject) => {
       const body = {
        'nrCpf': '00000000000',
        'dtNascimento': ''
      };

      let headers = new Headers({
        'Content-Type': 'application/json'
      });

      let options = new RequestOptions({
        headers: headers
      });

      this.http.post(this.API_URL, body, options)
          .subscribe((data: any) => {
            resolve(data);
          }, (err: any) => {
            reject(err);
          });
    }); 
  } 

When I debug my application the request falls into this filter:

@WebFilter("*")
public class CacheFilter implements Filter {


    @Override
    public void init(FilterConfig fConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String page = httpRequest.getRequestURI();


        httpResponse.setHeader("Access-Control-Allow-Origin","*");
        httpResponse.setHeader("Access-Control-Allow-Methods","GET,POST");
        httpResponse.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");

        if (!page.contains("fontawesome-webfont.eot") && !page.contains("/js/lib/") && !page.contains("/css/")) {
            httpResponse.setHeader("Expires", "-1");
            httpResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
            httpResponse.setHeader("Pragma", "no-cache");
        } else {
            httpResponse.setHeader("Cache-Control", "max-age=" + 604800);
            httpResponse.setDateHeader("Last-Modified", new Date().getTime());
        }
       chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }
}

The error is thrown when the chain.doFilter(request, response); when I make the same requisition with postman the function works, but I make the requisition with the raw data and the content-type with application/json, in my Ionic application I have made the header content-tyoe application/json and thrown the same error.

like image 925
Ronaiza Cardoso Avatar asked Sep 03 '25 02:09

Ronaiza Cardoso


2 Answers

Well the actual problem occurs because the JavaScript runtime performs a so called "preflight" request using the HTTP OPTIONS method in case of CORS. More details can be found here. If you don't provide an OPTIONS method in your server, this results in the described exception. Thus, you have 2 alternatives to solve this problem:

  1. You create a method annotated with "@OPTIONS" in your REST service like this:

    @OPTIONS
    @Path("/loginCpf")
    public Response optionsBeneficiarioCpf() {
       return Response.ok().header(HttpHeaders.ALLOW, HttpMethod.POST).build();
    }
    
  2. You handle the OPTIONS requests in a generic fashion, for instance within the CORS filter as described here.

like image 95
Jeff S. Avatar answered Sep 04 '25 16:09

Jeff S.


I finnaly find the answer, my Java backend was not prepared to receive requisitions of another resources so this happen. So I have made a Cors Filter to solve this issue.

this is the filter:

package yor.package.addres.goes.here;

import java.io.IOException;

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.HttpServletResponse;

public class CorsFilter implements Filter {

    @Override
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        resp.addHeader("Access-Control-Allow-Origin","*");
        resp.addHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
        resp.addHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");

        // Just ACCEPT and REPLY OK if OPTIONS
      // TODO removing this if
        if ( request.getMethod().equals("OPTIONS") ) {
            resp.setStatus(HttpServletResponse.SC_OK);
            return;
        }

        chain.doFilter(request, servletResponse);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {}

}
like image 45
Ronaiza Cardoso Avatar answered Sep 04 '25 17:09

Ronaiza Cardoso