使用 Jersey 通过 RESTfull 服务上传文件和资源配置不可修改?

Posted

技术标签:

【中文标题】使用 Jersey 通过 RESTfull 服务上传文件和资源配置不可修改?【英文标题】:Uploading file using Jersey over RESTfull service and The resource configuration is not modifiable? 【发布时间】:2013-08-17 15:50:57 【问题描述】:
@Path("file.upload")
public class UploadFileService 
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
        @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail) 

    System.out.println("-----------------UploadFileService------------------1.");
    // Should we use a disk or DB? Decided to use DISK
    // Path should be read from properties-files
    String uploadedFileLocation = "//uploaded/" + fileDetail.getFileName();

    // save it
    writeToFile(uploadedInputStream, uploadedFileLocation);

    String output = "File uploaded to : " + uploadedFileLocation;
    // All went OK
    return Response.status(200).entity(output).build();


 WARNING: No injection source found for a parameter of type public javax.ws.rs.core.Response com.insame.service.UploadFileService.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition) at index 0.

SEVERE:   WebModule[/insame]StandardWrapper.Throwable
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public javax.ws.rs.core.Response com.insame.service.UploadFileService.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition) at index 0.; source='ResourceMethodhttpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocablehandler=MethodHandlerhandlerClass=class com.insame.service.UploadFileService, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@47bee27a], handlingMethod=public javax.ws.rs.core.Response com.insame.service.UploadFileService.uploadFile(java.io.InputStream,com.sun.jersey.core.header.FormDataContentDisposition), parameters=[Parameter [type=class java.io.InputStream, source=file, defaultValue=null], Parameter [type=class com.sun.jersey.core.header.FormDataContentDisposition, source=file, defaultValue=null]], responseType=class javax.ws.rs.core.Response, nameBindings=[]']
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:410)
    at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:157)
    at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:280)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
    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.processWithException(Errors.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:277)
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:262)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)

我在UploadFileService下实现了这样的测试服务:

@GET
@Path("count")
@Produces("text/plain")
public String countREST() 
    return "1 one 1";

我得到了这个异常记录:

FINE:   [Web-Security] hasResource perm: ("javax.security.jacc.WebResourcePermission" 

"/webresources/file.upload/count" "GET")
SEVERE:   WebModule[/insame]StandardWrapper.Throwable
java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
    at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:257)
WARNING:   StandardWrapperValve[com.insame.service.ApplicationConfig]: Allocate exception for servlet com.insame.service.ApplicationConfig
java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
    at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:257)
    at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:205)
    at org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:435)
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:261)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)

环境

Netbeans7.3.1 Glassfish 4.0 带有 Glassfish 4.0 的泽西 2

【问题讨论】:

对于ResourceConfig 解决方案,请参阅***.com/a/43926819/548473 【参考方案1】:

为了在您的 Jersey 应用程序中使用 multipart,您需要在您的应用程序中注册 MultiPartFeature,即:

public class ApplicationConfig extends Application 

    public Set<Class<?>> getClasses() 
        final Set<Class<?>> resources = new HashSet<Class<?>>();

        // Add your resources.
        resources.add(UploadFileService.class);

        // Add additional features such as support for Multipart.
        resources.add(MultiPartFeature.class);

        return resources;
    

有关更多信息,请参阅泽西岛用户指南中的Multipart 部分。

对于您面临的第二个问题,请尝试重新启动 GlassFish 服务器,我不确定 NetBeans 在更改后如何重新加载 Jersey 应用程序(如果这没有帮助,请发布您的 ApplicationConfig)。

【讨论】:

非常感谢!错误消息已更改,我在 pom.xml 中发现了一个错误。我在 pom.xml 中使用旧的多部分版本。 WELD-001408 在注入点 [[BackedAnnotatedParameter] [BackedAnnotatedConstructor] @Inject public org.glassfish.jersey.media.multipart.internal.MultiPartReaderServerSide(@Context Providers,提供者)] 这可能与您的 .war 中有一些 Jersey 2.x 位有关(而它们同时在 GF 类路径上)。您可以在 pom.xml 中将jersey-media-multipart 工件标记为提供吗?它已经是 GF 4.0 的一部分。 就是这样!!现在它正在工作! org.glassfish.jersey.mediajersey-media-multipart2.2provided 我没有使用 Maven,但配置相同,但没有找到 GF4 球衣类!我能做什么? 在将旧的 Jersey 1 项目合并到 Jersey 2 项目后,我遇到了这个问题。我认为解决方案不是公认的答案,而是对 POM 和 Web XML 文件的修复...【参考方案2】:

我遇到了同样的问题,想避免创建自定义应用程序类。它没有很好的文档记录,但是如果你想添加 Multipart 功能,你所要做的就是将它添加到你的 web.xml jersey servlet 配置中:

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

我还添加了一个日志过滤器。

【讨论】:

您的解决方案是最好的! 我也无法让它工作。它是否需要按特定顺序放置在某个地方?你有没有机会了解整个 pom 的要点? 这是最简单的方法,而且效果很好!强烈推荐!【参考方案3】:

如果你使用的是jetty server和jersey servlet,那么你可以通过在你已经启动jetty server的主类中添加以下代码来解决这个问题,

ServletHolder jerseyServlet = context.addServlet( org.glassfish.jersey.servlet.ServletContainer.class, "/*"); jerseyServlet.setInitOrder(0);

      // Tells the Jersey Servlet which REST service/classes to load.
      jerseyServlet
              .setInitParameter(
                      "jersey.config.server.provider.classnames",
                      <Your entry point class's canonical name>
                              + ";org.glassfish.jersey.media.multipart.MultiPartFeature");

【讨论】:

【参考方案4】:

稍微澄清一下

使用

import org.glassfish.jersey.media.multipart.MultiPartFeature
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

不是

com.sun.jersey.*

只有在使用org.glassfish.jersey.media.multipart.*时才对我有用

在 ApplicationConfig 中只需将 MultiPartFeature 注册为

import org.glassfish.jersey.media.multipart.MultiPartFeature;

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application 

    @Override
    public Set<Class<?>> getClasses() 
        Set<Class<?>> resources = new java.util.HashSet<>();
        resources.add(UploadFileService.class);
        resources.add(MultiPartFeature.class);
        return resources;
    

【讨论】:

Hlleo 伙计们,我正在使用 Wildfly 服务器,我可以在我的 ApplicationConfig 中使用 import org.glassfish.jersey.media.multipart.* 吗,如果可以,你能告诉我应该添加什么依赖项吗在我的 pom.xml 中,因为我在我的项目中收到此错误:javax.ws.rs.NotSupportedException:找不到类型的消息正文阅读器:类 com.sun.jersey.core.header.FormDataContentDisposition 的内容类型:multipart/ form-data;,谢谢你。【参考方案5】:

我使用的是 Jersey 1.9.1。 org.glassfish...... 适用于 Jersey 2。对于 Jersey 1,您最好使用 com.sun... 类。

【讨论】:

建议您编辑您第一次尝试回答问题的帖子(即this post),而不是添加两个帖子作为您的答案。谢谢。【参考方案6】:

如果您希望使用注解,可以使用与 FormDataMultiPart 等效的 @FormDataParam("file")。

使用如下示例代码提取:

public Response uploadFile( **@FormDataParam("file")** InputStream fileInputStream,
             @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) 

【讨论】:

以上是关于使用 Jersey 通过 RESTfull 服务上传文件和资源配置不可修改?的主要内容,如果未能解决你的问题,请参考以下文章

Jersey REST 服务上的用户身份验证

使用 jersey 客户端通过 HTTPS 调用 api 时出现错误 handshake_failure。我已关闭服务器证书有效性检查

iphone:安全的restfull服务器“此服务器的证书无效

带有 XML 参数的 REST 服务操作上的 HTTP 错误 415 不受支持的媒体类型(Jersey + Jetty)

Restfull规范

使用 jersey 与 RESTful Web 服务进行服务器推送