405 Method Not Allowed is coming as Http Status 500 in RestEasy

喜夏-厌秋 提交于 2019-12-24 16:53:20

问题


Currently developing a Restful Service using RestEasy Framework.

Facing a trouble when it comes to handling 405 - javax.ws.rs.NotAllowedException: RESTEASY003650: No resource method found for POST, return 405 with Allow header.

Already written a ErrorHandler for NotAllowedException using ExceptionMapper and registered the provider in root application which extends javax.ws.rs.core.Application.

But still it returns 500 error and sets the Http Status to 500 instead of 405. Whereas other handlers written for 400 and 404 are working fine.

Using RestEasy's latest version: 3.0.16.Final

Here's the code for NotAllowedExceptionHandler and registering the same in application.

@Provider
public class NotAllowedExceptionHandler implements ExceptionMapper <NotAllowedException>
    {
        @Override
        public Response toResponse( NotAllowedException exception )
            {
                String bodyOfResponse = exception.getMessage();
                APIResponse response = new APIResponse( false , null , Status.METHOD_NOT_ALLOWED , HttpServletResponse.SC_METHOD_NOT_ALLOWED ,
                        bodyOfResponse );
                return Response.status( response.getStatus() ).entity( response ).build();
            }
    }

public class RootApplication extends Application
    {
        @Override
        public Set <Class <?>> getClasses()
            {
                Set <Class <?>> classes = new HashSet <Class <?>>();

                /* Specify resource classes to be loaded */
                classes.add( ErrorResource.class );

                /* Specify exception handler classes to be loaded */
                classes.add( ResourceGoneExceptionHandler.class );
                classes.add( RequestTooLargeExceptionHandler.class );
                classes.add( SearchExceptionHandler.class );
                classes.add( ServiceUnavailableExceptionHandler.class );
                classes.add( UnauthorizedExceptionHandler.class );
                classes.add( EntityNotFoundExceptionHandler.class );
                classes.add( JDOObjectNotFoundExceptionHandler.class );
                classes.add( NucleusObjectNotFoundExceptionHandler.class );
                classes.add( ResourceNotFoundExceptionHandler.class );
                classes.add( APIExceptionHandler.class );
                classes.add( ParseExceptionHandler.class );
                classes.add( InternalServerErrorExceptionHandler.class );
                classes.add( IllegalArgumentExceptionHandler.class );
                classes.add( JDOFatalUserExceptionHandler.class );
                classes.add( JDOUserExceptionHandler.class );
                classes.add( FatalN`enter code here`ucleusUserExceptionHandler.class );
                classes.add( IOExceptionHandler.class );
                classes.add( UnrecognizedPropertyExceptionHandler.class );
                classes.add( NotAllowedExceptionHandler.class);
                classes.add( NotSupportedExceptionHandler.class);

                /* Specify filter classes to be loaded */
                classes.add( RequestFilter.class );

                return classes;

            }
    }

Scenario: Trying to execute the resource url with wrong Http Method - POST instead of PATCH.

Here's the exception stacktrace for the same:

org.jboss.resteasy.spi.UnhandledException: org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: com.adaptavant.distributedsource.objects.APIResponse of media type: application/octet-stream
        at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:180)
        at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:236)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:225)
        at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:62)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:50)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:260)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:326)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
        at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:78)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
        at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:148)
        at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:468)
        at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
        at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
        at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:256)
        at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
        at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
        at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
        at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: com.adaptavant.distributedsource.objects.APIResponse of media type: application/octet-stream
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:66)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:176)
        ... 34 more
    E 2016-04-03 14:01:38.444
    com.adaptavant.distributedsource.exception.handler.InternalServerErrorExceptionHandler toResponse: 
     Message: null
    Exception Class: class java.lang.Exception
    java.lang.Exception
        at com.adaptavant.distributedsource.resource.ErrorResource.handlePostError500(ErrorResource.java:105)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:44)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:395)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:202)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
        at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327)
        at org.mortbay.jetty.servlet.Dispatcher.error(Dispatcher.java:135)
        at org.mortbay.jetty.Response.sendError(Response.java:274)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:475)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
        at org.mortbay.jetty.Server.handle(Server.java:326)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
        at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
        at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
        at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:256)
        at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
        at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
        at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
        at java.lang.Thread.run(Thread.java:745)

Please help in this regards.

Thanks in advance.


回答1:


RestEasy does not know how to process APIResponse. Add type to the Response of NotAllowedExceptionHandler.toResponse method to resolve the issue:

Response.status( response.getStatus() ).entity( response ).type(MediaType.<type>).build(); 

For e.g for JSON type the code will look like below:

Response.status( response.getStatus() ).entity( response ).type(MediaType.APPLICATION_JSON).build(); 

Full method:

 @Provider
    public class NotAllowedExceptionHandler implements ExceptionMapper <NotAllowedException>
        {
            @Override
            public Response toResponse( NotAllowedException exception )
                {
                    String bodyOfResponse = exception.getMessage();
                    APIResponse response = new APIResponse( false , null , Status.METHOD_NOT_ALLOWED , HttpServletResponse.SC_METHOD_NOT_ALLOWED ,
                            bodyOfResponse );
                    return Response.status( response.getStatus() ).entity( response ).type(MediaType.APPLICATION_JSON).build();
                }
        }


来源:https://stackoverflow.com/questions/36374177/405-method-not-allowed-is-coming-as-http-status-500-in-resteasy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!