1. ホーム
  2. java

[解決済み] REST Web サービスからクライアントにファイルを送信する正しい方法は何ですか?

2022-09-15 09:50:18

質問

RESTサービスを開発し始めたところですが、RESTサービスからクライアントにファイルを送信するという難しい状況に出くわしました。これまでのところ、私は単純なデータ型(文字列、整数など)を送信する方法のコツをつかんでいますが、ファイルを送信することは別の問題です。なぜなら、あまりにも多くのファイル形式があり、どこから始めればよいのかさえ分からないからです。私のRESTサービスはJavaで作られており、Jerseyを使用しています。私はすべてのデータをJSONフォーマットで送信しています。

base64エンコーディングについて読みました。ある人はそれが良いテクニックだと言い、他の人はファイルサイズの問題からそうではないと言います。正しい方法は何でしょうか。これは、私のプロジェクトにおける単純なリソース クラスがどのように見えるかです。

import java.sql.SQLException;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;

import com.mx.ipn.escom.testerRest.dao.TemaDao;
import com.mx.ipn.escom.testerRest.modelo.Tema;

@Path("/temas")
public class TemaResource {

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public List<Tema> getTemas() throws SQLException{

        TemaDao temaDao = new TemaDao();        
        List<Tema> temas=temaDao.getTemas();
        temaDao.terminarSesion();

        return temas;
    }
}

ファイル送信のコードはこんな感じでしょうか。

import java.sql.SQLException;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/resourceFiles")
public class FileResource {

    @GET
    @Produces({application/x-octet-stream})
    public File getFiles() throws SQLException{ //I'm not really sure what kind of data type I should return

        // Code for encoding the file or just send it in a data stream, I really don't know what should be done here

        return file;
    }
}

どのようなアノテーションを使用すればよいのでしょうか?ある人は @GET を使って @Produces({application/x-octet-stream}) というのは正しい方法なのでしょうか?私が送っているファイルは、クライアントがファイルを参照する必要がないように、特定のものです。どなたか、どのようにファイルを送ればいいのか、教えていただけませんか?それとも、JSONオブジェクトとして送信するためにエンコーディングは必要ないのでしょうか?あなたが与えるかもしれない助けのためにありがとうございます。

どのように解決するのですか?

バイナリデータをbase64でエンコードしてJSONでラップするのはお勧めしません。レスポンスのサイズが無駄に大きくなり、速度が低下するだけです。

単に GET を使ってファイルデータを提供し application/octect-stream のファクトリーメソッドの一つを使用して javax.ws.rs.core.Response (JAX-RSのAPIの一部なので、Jerseyに縛られることはありません)のファクトリーメソッドの一つを使います。

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile() {
  File file = ... // Initialize this to the File path you want to serve.
  return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
      .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
      .build();
}

もし、実際の File オブジェクトがなく InputStream , Response.ok(entity, mediaType) も同様に処理できるはずです。