私は、ジャージーベースの安らかなサービス実装戦略を使用して、ファイルのアップロードに使用されるサービスを構築しています。私のサービスクラス名はUploadFileService.Javaです(以下のコードを参照)。
package com.jerser.service;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.OutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.Sun.jersey.core.header.FormDataContentDisposition;
import com.Sun.jersey.multipart.FormDataParam;
@Path("/fileUpload")
public class UploadFileService {
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) {
String uploadedFileLocation = "d://uploaded/" + fileDetail.getFileName();
// save it
writeToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded to : " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
// save uploaded file to new location
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(
uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
これらは、lib内にあるJARファイルです。
aopalliance-repackaged-2.4.0-b10.jar asm-debug-all-5.0.2.jar hk2-api-2.4.0-b10.jar hk2-locator-2.4.0-b10.jar hk2-utils-2.4.0-b10.jar javassist-3.18.1-GA.jar javax.annotation-api-1.2.jar javax.inject-2.4.0-b10.jar javax.servlet-api-3.0.1.jar javax.ws.rs-api-2.0.1.jar jaxb-api-2.2.7.jar jersey-client.jar jersey-common.jar jersey-container-servlet-core.jar jersey-container-servlet.jar jersey-core-1.11.jar jersey-guava-2.17.jar jersey-media-jaxb.jar jersey-multipart-1.18.jar jersey-server.jar org.osgi.core-4.2.0.jar osgi-resource-locator-1.0.1.jar persistence-api-1.0.jar validation-api-1.1.0.Final.jar
Tomcatサーバーを起動しようとすると、次のエラーが表示されます。
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.jerser.service.UploadFileService.uploadFile(Java.io.InputStream,com.Sun.jersey.core.header.FormDataContentDisposition) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.jerser.service.UploadFileService, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@d3e2d4]}, definitionMethod=public javax.ws.rs.core.Response com.jerser.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:528)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.Java:166)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.Java:327)
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:324)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.Java:338)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.Java:171)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.Java:363)
at javax.servlet.GenericServlet.init(GenericServlet.Java:160)
at org.Apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.Java:1176)
at org.Apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.Java:1102)
at org.Apache.catalina.core.StandardWrapper.load(StandardWrapper.Java:1009)
at org.Apache.catalina.core.StandardContext.loadOnStartup(StandardContext.Java:4885)
at org.Apache.catalina.core.StandardContext$3.call(StandardContext.Java:5212)
at org.Apache.catalina.core.StandardContext$3.call(StandardContext.Java:5207)
at Java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at Java.util.concurrent.FutureTask.run(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
インターネット上で、RESTFul APIを使用してMULTIPARTファイルをアップロードする方法を示す例がたくさんあります。しかし、同じソリューションで。これらのコードも実行できません。 JARファイルに何か問題があると思います。誰もこれで私を助けてくれますか?
jersey-multipart-1.18.jar
を取り除きます。これはJersey 1.xの場合です。これら2つを追加
Mavenでは、次の依存関係を使用します(mimepull
依存関係を明示的に追加する必要はありません。この依存関係を取り込むためです)。
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.17</version> <!-- Make sure the Jersey version matches
the one you are currently using -->
</dependency>
次に、MultiPartFeature
を登録する必要があります。設定にResourceConfig
を使用している場合は、単に
register(MultiPartFeature.class);
Web.xmlを使用している場合は、<init-param>
としてクラスをJerseyサーブレットに追加できます
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
登録するプロバイダーが複数ある場合は、各プロバイダークラスをコンマまたはセミコロンで区切ることができます。これと同じparam-name
を2回使用することはできません。 スアラブの答え を参照
[〜#〜] update [〜#〜]
また、jersey-multipart-1.18.jar
を削除すると、インポートされていないクラスのコンパイルエラーが発生します。ほとんどの場合、クラス名は同じままで、パッケージだけが変更されています。
org.glassfish.jersey.media.multipart.FormDataParam
org.glassfish.jersey.media.multipart.FormDataContentDisposition
別のModelValidationException
にアクセスしている場合は、例外の他の原因に関する情報へのリンクがあります。
私も同じ例外を受け取りました。web.xmlで次の変更を行いました。
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.moxy.json.MoxyFeature;org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
ジャージ2.7を2.9に変更しました。この2の変更により問題が解決したかどうかはわかりません。
MultiPartFeatureを登録します。 web.xmlでJerseyサーブレットに追加します。
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
この非常に一般的なエラーのもう1つの考えられる原因は、パラメーターで複数の宣言が宣言されている場合、Jerseyが最後の注釈に関連付けられているファクトリーのみを検索することです。 ( バグレポート を参照)
これが修正されるまで、@FormDataParam
以外の注釈を使用している場合は、最後に来る必要があります。
これは動作します:
@NotEmpty @FormDataParam("myParam") String myParam
これはしません:
@FormDataParam("myParam") @NotEmpty String myParam
Scalaでも同じ問題が発生し、これが解決に役立ちました。 ScalaでDropwizardを使用する人を支援するために、いくつかのScalaの詳細を追加したいだけです。 ScalaおよびDropwizardプロジェクトでMultiPartFeatureを「登録」する方法の例を次に示します。
package org.research.s3.service
import io.dropwizard.Application
import io.dropwizard.setup.Environment
import org.research.s3.service.resource._
import org.research.service.s3.resource.UploadResource
import org.glassfish.jersey.media.multipart.{FormDataParam,MultiPartFeature}
class CmdaaApp() extends Application[CmdaaAppConfig] {
override def run(t: CmdaaAppConfig, env: Environment): Unit = {
env.jersey().register(new RootResource)
//Need this to make the file upload code work in
env.jersey().register(new MultiPartFeature)
env.jersey().register(new UploadResource(curBucket))
}
}
object CmdaaApp {
def main(args: Array[String]): Unit = new CmdaaApp().run(args: _*)
}
アップロードを行うUploadResourceのコードは次のとおりです。
package org.research.service.s3.resource
import Java.io.{FileInputStream, InputStream}
import com.google.gson.{Gson, GsonBuilder}
import javax.ws.rs.core.MediaType.APPLICATION_JSON
import javax.ws.rs._
import javax.ws.rs.core.Response
import javax.ws.rs.core.MediaType
import org.research.util.OptionSerializer
import org.research.s3.service.resource.s3Bucket
import org.glassfish.jersey.media.multipart.{FormDataParam,MultiPartFeature}
@Path("/file")
class UploadResource(currentBucket: s3Bucket) {
val gsonb = new GsonBuilder()
gsonb.registerTypeAdapter(classOf[Option[Any]], new OptionSerializer)
val gson = gsonb.create
@POST
@Path("upload")
@Produces(Array(APPLICATION_JSON))
@Consumes(Array(MediaType.MULTIPART_FORM_DATA))
// def uploadFile(): Response = {
def uploadFile(@FormDataParam("file") uploadedInputStream: InputStream): Response = {
/* Need code here to get a uuid for the file name
Then return the uuid if we have success and of course 200
*/
Response.ok.entity(currentBucket.upload("testName",uploadedInputStream,false)).build()
//Response.ok().build()
}
}
このコードはs3バケットを参照していますが、それは必要ありません。その呼び出しをコードで置き換えるだけで、着信ファイルのデータを通常のファイルにダウンロードできます。 スカラ
誰かが@FormDataParam
を@ApiOperation
swagger注釈とともに使用している場合、ここで述べたように(現時点のswagger最新バージョンでは)動作しません。
ファイルをアップロードしようとしたときに同じ問題が発生しました。問題の解決策を見つけるまで、私は多くの時間を費やしました。
1. JARファイルのバージョンを変更した場合、バージョンの競合が発生する可能性があります!
アーティファクト/ライブラリをクリーンアップし、プロジェクトを再構築します。
2. UploadFileServiceクラスも登録する必要があります。
register(MultiPartFeature.class);
register(UploadFileService.class);
それが誰かを助け、あなたの時間を節約することを願っています。