为什么在启动 REST 服务时添加注释 FormDataParam 会引发异常?
Why does adding an annotation FormDataParam raise an exception when starting a REST service?
Jersey documentation(版本2.29.1)有如下例子(Example 9.50. Use of @FormDataParam annotation
):
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postForm(
@DefaultValue("true") @FormDataParam("enabled") boolean enabled,
@FormDataParam("data") FileData bean,
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition) {
// ...
}
以我为例,方法如下:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition
){
return Response.ok().build();
}
当服务器启动时(也就是说,它甚至没有到达方法调用),我得到以下错误(使用 Apache Tomcat / 8.5.16):
Type Exception Report
Message Servlet.init() for servlet [rest.ApplicationConfig] threw
exception
Description The server encountered an unexpected condition that
prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Servlet.init() for servlet
[rest.ApplicationConfig] threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
Root Cause
java.lang.IllegalStateException: The resource configuration is not
modifiable in this context.
org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:246)
org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:193)
org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:426)
org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:306)
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:346)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
Note The full stack trace of the root cause is available in the server
logs.
此外,如果您删除 @FormDataParam (" file ") InputStream file
和 @FormDataParam ("file") FormDataContentDisposition fileDisposition
,则服务器正常启动:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(){
return Response.ok().build();
}
服务器本身的配置没有使用 web.xml,如果重要的话:
@ApplicationPath("/")
public class ApplicationConfig extends Application {
}
这样试了,结果完全一样:
@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig(){
register(MultiPartFeature.class);
}
}
问题是什么以及如何解决?
的确,问题出在ApplicationConfig
class.
首先,class 在 rest
包中。
其次,这个包需要添加到ApplicationConfig
class.
的构造函数中
package rest;
@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig(){
register(MultiPartFeature.class);
packages("rest");
}
}
Jersey documentation(版本2.29.1)有如下例子(Example 9.50. Use of @FormDataParam annotation
):
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postForm(
@DefaultValue("true") @FormDataParam("enabled") boolean enabled,
@FormDataParam("data") FileData bean,
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition) {
// ...
}
以我为例,方法如下:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataContentDisposition fileDisposition
){
return Response.ok().build();
}
当服务器启动时(也就是说,它甚至没有到达方法调用),我得到以下错误(使用 Apache Tomcat / 8.5.16):
Type Exception Report
Message Servlet.init() for servlet [rest.ApplicationConfig] threw exception
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Servlet.init() for servlet [rest.ApplicationConfig] threw exception org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Thread.java:748)
Root Cause
java.lang.IllegalStateException: The resource configuration is not modifiable in this context. org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:246) org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:193) org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:426) org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:306) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:346) javax.servlet.GenericServlet.init(GenericServlet.java:158) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Thread.java:748)
Note The full stack trace of the root cause is available in the server logs.
此外,如果您删除 @FormDataParam (" file ") InputStream file
和 @FormDataParam ("file") FormDataContentDisposition fileDisposition
,则服务器正常启动:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/test")
public Response saveFiles(){
return Response.ok().build();
}
服务器本身的配置没有使用 web.xml,如果重要的话:
@ApplicationPath("/")
public class ApplicationConfig extends Application {
}
这样试了,结果完全一样:
@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig(){
register(MultiPartFeature.class);
}
}
问题是什么以及如何解决?
的确,问题出在ApplicationConfig
class.
首先,class 在 rest
包中。
其次,这个包需要添加到ApplicationConfig
class.
package rest;
@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig(){
register(MultiPartFeature.class);
packages("rest");
}
}