我正在使用泽西2.22.1来实现REST API。
我创建了一个自定义异常映射器,将运行时异常映射到我选择的特定HTTP响应代码。
@Provider
public class MyExceptionMapper implements ExceptionMapper<RuntimeException>
{
@Override
public Response toResponse(RuntimeException exception)
{
....
}
}
我的资源类配置为接受POST请求的多个参数。
@Path("rest/api/1.0/test")
public class MyResource
{
@NotNull(message = "Missing parameter 'param1'")
@FormParam("param1")
private String m_param1;
@NotNull(message = "Missing parameter 'param2'")
@FormParam("param2")
private String m_param2;
@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes("application/x-www-form-urlencoded")
public Response test(String body)
{
...
}
}
当我发送不带任何参数的POST请求时:
curl -X POST http://192.168.0.2:9989/myApp/rest/api/1.0/test
我希望调用我的自定义异常映射器,但它没有被调用。相反,我得到了一堆非法状态异常。
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 6
java.lang.IllegalStateException: The @FormParam is utilized when the content type of the request entity is not application/x-www-form-urlencoded
at org.glassfish.jersey.server.internal.inject.FormParamValueFactoryProvider$FormParamValueFactory.ensureValidRequest(FormParamValueFactoryProvider.java:183)
at org.glassfish.jersey.server.internal.inject.FormParamValueFactoryProvider$FormParamValueFactory.getForm(FormParamValueFactoryProvider.java:167)
at org.glassfish.jersey.server.internal.inject.FormParamValueFactoryProvider$FormParamValueFactory.provide(FormParamValueFactoryProvider.java:118)
at org.glassfish.jersey.server.internal.inject.ParamInjectionResolver.resolve(ParamInjectionResolver.java:134)
at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:211)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:234)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:357)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:767)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:706)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
有人能解释为什么我的自定义异常映射器没有被调用吗?
注意,如果我在资源方法中抛出一个RuntimeException,然后发送一个有效的POST请求,那么就会调用异常映射器。所以我知道它在某种程度上起作用。
更新
我发现如果我将以下内容添加到HTTP请求中:
-H“内容类型:应用程序/x-www-form-urlencoded”
然后调用我的ConstraintViolationExceptionMapper。
@Provider
public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException>
{
...
}
但是如果我删除ConstraintViolationExceptionMapper
,我的自定义异常映射器仍然没有被调用。
公认的答案似乎不再正确。
所以我们从来没有机会处理它。
现在不是这样。检查中的正确解决方案https://stackoverflow.com/a/45478604/1271372.
我遵循这一点,实现了ExceptionMapper
当然,这应该返回代码400。我必须将响应体定制为JSON,而不是纯文本。
遵循JAX-RS规范,对于@FormParam
和其他@XxxParam
s,当参数解析过程中发生异常时,泽西抛出一个已经映射的异常。这是为了遵循规范以返回正确的响应状态。所以我们永远没有机会处理它。
泽西已经有一个ValidationException
的映射器,它是ConstraintViolationException
的超类。因此,当您为ConstrainViolationException
提供映射器时,它比ValidationException
的映射器更具体,因此它被调用。
即使我为ValidationException提供了映射器,当我发送没有头的请求时也不会调用它。你知道为什么吗?
因为参数解析发生在验证之前。
我有以下资源,它使用映射到POJO的JSON。 下面是 POJO 类: 当我发送带有正文{“title”:“Test title”}的POST请求时,一切正常。正如预期的那样,响应是测试。但是,当我将请求更改为{“titlee”:“Test title”}时,服务器会回复如下: 无法识别的字段“titlee”(类com.my.package.MyObject),在[Source:org.glass
首先,我对这个问题太长表示最诚挚的歉意,但老实说,我不知道如何缩短它,因为每个部分都是一个特例。诚然,我可能对此视而不见,因为我已经把头撞到墙上好几天了,我开始绝望了。 我向所有通读这本书的人表示最大的尊重和感谢。 我希望能够通过使用Jersey ExceptionMapers将Shiro的AuthenticationException及其子类映射到JAX-RS响应,Jersey例外映射器是使用G
再一次在布罗斯沃尔,一切都很完美。在PhoneGap应用程序上仅GET request有效
我正在使用ApacheCXF、Spring和JAX-RS构建一个REST web服务,当输入JSON验证失败时,我需要在其中发送自定义异常。 我没有使用业务逻辑,而是尝试使用CXF、JAX-RS的现成bean验证功能。 Bean验证工作正常,但是,它总是抛出500个异常,这是不太有用的。根据留档,它是org.apache.cxf.jaxrs.validation.ValidationExcepti
我能够使用Json输出运行Jersey,并且能够在没有任何问题的情况下使用Json映射获得“get”请求。 我也有一些JSON方法,它们是“post”方法,它们映射到Java类,如下面的方法- 供您参考,我在这里或这里遵循指南 在给出一个有效的post请求时,它们都开始抛出下面的错误-
我想在从AbstractEndPoint派生的endpoint上使用不同的jackson ObjectMapper实例(而不是在其他映射URL上使用的实例)。 为了澄清这个问题,我不想更改或自定义对象映射器,它由不同的URL使用,不同的URL来自AbstractEndpoints(如HealtEndpoint、MetricsEndpoint)。我想专门将新的对象映射器注入到管理endpoint中。