我在使用javax.ws.rs的REST服务中工作,在Glassfish下运行,我在不同的服务器上有一些奇怪的行为差异,关于空查询参数的解释。 请注意,为了保护无辜者,服务的实际名称和被认为不重要的实施细节已经更改或被忽略,以保护无辜者。
一些(大多数)服务器处理请求
(即提供名为status的查询参数,但在=符号后没有值)等同于
基本上让查询参数为null,但有些人认为查询参数的值为"" (空字符串)。
这是我的问题,因为:
/* In a Resource class, I have this method defined: */
@GET
@Path("/orders")
public Response getOrders(@QueryParam("status") OrderStatus orderStatus) throws Exception {
/* code to pull orders, optionally by status, and return them in a Response */
}
/* ... and elsewhere, our enum */
public enum OrderStatus {
RECEIVED, ACKNOWLEDGED, CANCELLED
}
当有人将上面的第一个请求发送到将其视为空字符串的服务器时,我在表单中收到错误:
"java.lang.IllegalArgumentException: No enum constant com.fqcn.OrderStatus."
(因为""不是它尝试自动构建的枚举中的有效值),如果请求命中其他服务器,它将成功检索订单列表。
为了调试,虽然我无法在正常执行下生成堆栈跟踪,但我能够编写一个ExceptionMapper,并明确地输出它的堆栈跟踪,所以我提出了这个:< / p>
com.sun.jersey.server.impl.model.parameter.QueryParamInjectableProvider$QueryParamInjectable.getValue(QueryParamInjectableProvider.java:74),
com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46),
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153),
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203),
com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75),
com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288),
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147),
com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108),
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147),
com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84),
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469),
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400),
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349),
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339),
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416),
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537),
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708),
javax.servlet.http.HttpServlet.service(HttpServlet.java:770),
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550),
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281),
org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175),
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java),
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655),
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595),
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161),
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331),
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231),
com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317),
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195),
com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860),
com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757),
com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056),
com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229),
com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137),
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104),
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90),
com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79),
com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54),
com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59),
com.sun.grizzly.ContextTask.run(ContextTask.java:71),
com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532),
com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513),
java.lang.Thread.run(Thread.java:724)
我的问题是:我不知道这个查询 - 参数解释行为所在的位置(配置文件或类/ jar文件),并且我无法控制请求此操作的客户端。此外,&#34;大红色按钮&#34;从一个已知的商品中删除违规服务器并建立新克隆的方法。实例是耗时的,必须非常小心。
我想回答的问题是:如果在Glassfish或Jackson(或服务堆栈的另一层?)中的任何地方,是否配置了这个空查询参数解释行为,以及如何更改它?