1

ファイルアップロードのRESTエンドポイントがDropwizardに実装されています。私はこれを初めて知り、勉強しようとしています。引数のコンストラクタがないとResourceConfigが原因でDropwizardファイルのアップロードが失敗する

@Path("/files") 
@Produces(MediaType.APPLICATION_JSON) 
public class FileUploadResource { 

    private final MyAppWebConfiguration configuration; 
    private static final Logger logger = LoggerFactory.getLogger(FileUploadResource.class); 

    public FileUploadResource(MyAppWebConfiguration configuration) { 
     this.configuration = configuration; 
    } 

    @POST 
    @Consumes(MediaType.MULTIPART_FORM_DATA) 
    public Response uploadFile(
      @FormDataParam("file") InputStream uploadedInputStream, 
      @FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException { 

     logger.info("Request to upload the file ", fileDetail.getFileName()); 
     final String uploadedFileLocation = configuration.getCsvUploadPath(); 
     final String fileName = fileDetail.getFileName(); 
     writeToFile(uploadedInputStream, uploadedFileLocation, fileName); 
     return Response.ok("File " + fileName + " is uploaded to the location " + uploadedFileLocation).build(); 
    } 

    // save uploaded file to new location 
    protected void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation, String fileName) throws IOException { 
     logger.info("Writing {} to {}", fileName, uploadedFileLocation); 
     final java.nio.file.Path outputPath = FileSystems.getDefault().getPath(uploadedFileLocation, fileName); 
     Files.copy(uploadedInputStream, outputPath, StandardCopyOption.REPLACE_EXISTING); 
     logger.info("Uploaded {} to the location {}", fileName, uploadedFileLocation); 
    } 

コードは正常に動作し、ファイルをアップロードできます。 私はhttps://gist.github.com/psamsotha/218c6bbeb6164bac7cbcに基づいて、以下のコードでそれをテストしようとしています:

public class FileUploadResourceTest extends JerseyTest { 

    private final static MyAppWebConfiguration mockConfiguration = mock(MyAppWebConfiguration.class); 

    @Override 
    public ResourceConfig configure() { 
     return new ResourceConfig(FileUploadResource.class) 
       .register(MultiPartFeature.class) 
       .register(new LoggingFilter(Logger.getAnonymousLogger(), true)); 
    } 

    @Override 
    public void configureClient(ClientConfig config) { 
     config.register(MultiPartFeature.class); 
    } 

    @Test 
    public void test() { 
     FileDataBodyPart filePart = new FileDataBodyPart("file", new File("/Users/rocky/Downloads/test.csv")); 
     filePart.setContentDisposition(FormDataContentDisposition.name("file").fileName("/Users/rocky/Downloads/test.csv").build()); 

     MultiPart multiPart = new FormDataMultiPart() 
       .bodyPart(filePart); 
     Response response = target("/files").request() 
       .post(Entity.entity(multiPart, MediaType.MULTIPART_FORM_DATA_TYPE)); 
     assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); 
     response.close(); 
    } 

このテストでは、以下のエラーで失敗します。

WARNING: The following warnings have been detected: WARNING: HK2 service reification failed for [com.my.app.resources.FileUploadResource] with an exception: 
MultiException stack 1 of 2 
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.my.app.resources.FileUploadResource class. 
    at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:192) 
    at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:178) 
    at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:128) 
    at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:179) 

は私がFileUploadResourceで引数なしのコンストラクタを持っていませんが、new ResourceConfig(FileUploadResource.class)を期待引数のコンストラクタはありません。ここで引数のコンストラクタに関する情報を渡すにはどうすればよいですか?

ここにお手伝いいただければ幸いです。また、コードとテストに関するその他のベストプラクティスを提案して、改善できるようにしてください。

事前に感謝します。

+0

試した@peeskilletの提案。 'FileDataBodyPart filePart = new FileDataBodyPart(" file "、新しいファイル("/Users/rocky/Downloads/test.csv ")); ( "/ Users/rocky/Downloads/test.csv")。build()); filePart.setContentDisposition(FormDataContentDisposition.name( "file")。 マルチパートマルチパート=新規FormDataMultiPart() .bodyPart(filePart); '。しかし、エラーを取得中[2016-04-08 10:41:29,089] io.dropwizard.jersey.errors.LoggingExceptionMapper:リクエストを処理中にエラーが発生しました:bdb68f36df42328e ! java.nio.file.NoSuchFileException:null/abc/Users/rocky/Downloads/test.csv'。 – Nikki

+0

test.csvを同じdirおよび変更されたパスに移動しました。 org.glassfish.jersey.test.inmemory.InMemoryConnector:エンティティを出力ストリームに書き込む際にエラーが発生しました。 ! java.io.FileNotFoundException:test.csv(そのようなファイルやディレクトリはありません)..javax.ws.rs.ProcessingException:エンティティを出力ストリームに書き込む際にエラーが発生しました。 java.io.FileNotFoundException:FileUploadResourceTest.testでのtest.CSV(そのようなファイルやディレクトリはありません) (FileUploadResourceTest.java:51) 'によって引き起こさFileUploadResourceTest.test(FileUploadResourceTest.java:51) で 。 行51は '.post(Entity.entity(multiPart、multiPart.getMediaType())); ' – Nikki

+1

http://stackoverflow.com/q/19871955/2587435 \ –

答えて

2

あなたはクラスとして

new ResourceConfig(FileUploadResource.class) 

をリソースに登録するとあなたはそれを作成するためにジャージーを語っています。しかし、ジャージーが何も知らない構成オブジェクトを受け入れるコンストラクタだけが存在するので、それをどのように作成するかはわかりません。代わりにオブジェクトとして登録するだけです。 Dropwizard(env.jersey().register(...))に登録しているのと同じ方法です。余談として

new ResourceConfig().regster(new FileUploadResource(mockConfiguration)) 
    ... 

、Dropwizardで我々は、明示的に JerseyTestを使用する必要はありません。 DropwizardにはJUnitルールが付属しています。これは明示的に独自の JerseyTestを実行しており、ルールで設定することができます。私が完全な例を投稿した this issueを参照してください。

関連する問題