как получить исходный файл в HttpRequest для загрузки файла - PullRequest
1 голос
/ 21 апреля 2011

У меня проблема с загрузкой файла в веб-сервис REST с использованием Java.Я не знаю, как получить исходный файл.Команда curl выглядит следующим образом:

curl --upload-file /home/student1/text1.txt http://localhost:20260/project/resources/user1/sub-folder/text1.txt

Мой вопрос: кто-нибудь знает, как получить URL исходного файла "/ home/student1/text1.txt "в методе REST web-сервиса @PUT? Или каким-либо другим способом его получить?

спасибо

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Я предполагаю, что curl использует mltipart / form-data в качестве типа контента для загрузки. Имя файла будет частью заголовка Content-Disposition первой части MIME.

2 голосов
/ 21 апреля 2011

Я не очень знаком с JAX-RS, но я думаю, что следующий код делает то, что вы ищете:

package org.restlet.example;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("project/resources/{user}/{directory}/{filename}")
public class JaxRsResource {
    private static final int BLOCK_SIZE = 8192;
    private static final Map<String, MediaType> MEDIA_TYPE_MAP = new HashMap<String, MediaType>();

    @Context
    private UriInfo uriInfo;

    @Context
    private HttpHeaders httpHeaders;

    @PathParam("user")
    private String user;

    @PathParam("directory")
    private String directory;

    @PathParam("filename")
    private String filename;

    @QueryParam("name")
    private String name;

    @QueryParam("type")
    private String type;

    static {
        MEDIA_TYPE_MAP.put("txt", MediaType.TEXT_PLAIN_TYPE);
        MEDIA_TYPE_MAP.put("gif", MediaType.valueOf("image/gif"));
        MEDIA_TYPE_MAP.put("jpg", MediaType.valueOf("image/jpeg"));
        MEDIA_TYPE_MAP.put("png", MediaType.valueOf("image/png"));
        MEDIA_TYPE_MAP.put("zip", MediaType.valueOf("application/zip"));
    }

    public JaxRsResource() {
    }

    @PUT
    @Consumes({"text/plain", "image/jpeg", "image/png", "image/gif", "application/zip"})
    public Response upload(final byte[] contents) throws IOException, URISyntaxException {
        FileOutputStream output = null;
        try {
            final File directories = new File(user, directory);
            directories.mkdirs();
            final File file = new File(directories, filename);
            output = new FileOutputStream(file);
            output.write(contents);
        } finally {
            if (output != null) {
                output.flush();
                output.close();
            }
        }
        return Response.created(uriInfo.getAbsolutePath()).build();
    }

    @GET
    @Produces({"text/plain", "image/jpeg", "image/png", "image/gif", "application/zip"})
    public Response output() throws IOException {
        final String extension = filename.substring(filename.lastIndexOf('.') + 1);
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        InputStream input = null;
        try {
            input = new FileInputStream(new File(new File(user, directory), filename));
            final byte[] buffer = new byte[BLOCK_SIZE];
            int read = 0;
            while ((read = input.read(buffer)) > -1) {
                output.write(buffer, 0, read);
            }
        } finally {
            if (input != null) {
                input.close();
            }
        }
        final byte[] byteArray = output.toByteArray();
        output.flush();
        output.close();
        return Response.ok(byteArray, MEDIA_TYPE_MAP.get(extension)).build();
    }

}

Я не проверял, безопасно ли пытаться выставить .. для user или directory, поэтому может потребоваться санация ввода. Кроме того, ошибки и исключения должны обрабатываться лучше.

Я проверил это с помощью curl, и он создает файл в файловой системе сервера, содержащий содержимое файла, переданного через --upload-file, который затем можно получить, выдав GET тому же ресурсу. Мне нужно было добавить заголовок Content-Type к запросу curl, чтобы он работал, хотя:

curl -v -T test.txt -H "Content-Type: text/plain" http://localhost:8182/project/resources/user1/sub-folder/test.txt

Я проверил это, используя Реализация Рестлета JAX-RS .

Эта новая версия отвечает вашим дополнительным требованиям поддержки параметров запроса, которые вы упомянули в другом комментарии. Я реорганизовал его для использования свойств вместо аргументов метода, поскольку списки аргументов становились громоздкими. Я узнал, что это безопасно для потоков из спецификации JAX-RS. Кроме того, я изменил код для поддержки простого текста и двоичных файлов, хотя я не пробовал его с разными кодировками файлов. Поскольку метод ожидает ввода байтового массива, я надеюсь, что инфраструктура JAX-RS делает правильные вещи и может сказать, какую кодировку использовать, если она указана в заголовке Content-Type запроса.

...