Создайте веб-службу Rest для получения изображения

Как бы вы разработали веб-службу на основе REST, которая получает файл изображения в форме InputStream? Если InputStream отправляется в конечную точку REST, как эта конечная точка получает его, чтобы создать файл изображения?


person c12    schedule 19.04.2011    source источник


Ответы (2)


Пример класса Java веб-службы REST для получения изображения

import java.io.ByteArrayInputStream;
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.FormParam;
import javax.ws.rs.POST;
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.Response;
import javax.ws.rs.core.UriInfo;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;


@Path("/upload")
public class Upload_Documents {


    private static final String UPLOAD_FOLDER = "c:/uploadedFiles/";

    @Context
    private UriInfo context;
    /**
     * Returns text response to caller containing uploaded file location
     * 
     * @return error response in case of missing parameters an internal
     *         exception or success response if file has been stored
     *         successfully
     */
    @POST
    @Path("/pic")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
            @FormDataParam("file") InputStream uploadedInputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail) {

        System.out.println("Called Upload Image");
        // check if all form parameters are provided
        if (uploadedInputStream == null || fileDetail == null)
            return Response.status(400).entity("Invalid form data").build();
        // create our destination folder, if it not exists
        try {
            createFolderIfNotExists(UPLOAD_FOLDER);
        } catch (SecurityException se) {
            return Response.status(500)
                    .entity("Can not create destination folder on server")
                    .build();
        }
        String uploadedFileLocation = UPLOAD_FOLDER + fileDetail.getFileName();
        try {
            saveToFile(uploadedInputStream, uploadedFileLocation);
        } catch (IOException e) {
            return Response.status(500).entity("Can not save file").build();
        }
        return Response.status(200)
                .entity("File saved to " + uploadedFileLocation).build();
    }
    /**
     * Utility method to save InputStream data to target location/file
     * 
     * @param inStream
     *            - InputStream to be saved
     * @param target
     *            - full path to destination file
     */
    private void saveToFile(InputStream inStream, String target)
            throws IOException {
        OutputStream out = null;
        int read = 0;
        byte[] bytes = new byte[1024];
        out = new FileOutputStream(new File(target));
        while ((read = inStream.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        out.flush();
        out.close();
    }
    /**
     * Creates a folder to desired location if it not already exists
     * 
     * @param dirName
     *            - full path to the folder
     * @throws SecurityException
     *             - in case you don't have permission to create the folder
     */
    private void createFolderIfNotExists(String dirName)
            throws SecurityException {
        File theDir = new File(dirName);
        if (!theDir.exists()) {
            theDir.mkdir();
        }
}
}
person Mallikarjuna    schedule 26.10.2017
comment
Мы хотели бы получить некоторые пояснения - person GGO; 26.10.2017
comment
Файл передается через HTTP POST с типом кодирования «multipart/form-data» от клиента к нашему веб-сервису. Таким образом, вы можете добавить несколько параметров в запрос POST в дополнение к файлу. Начнем с требований. Для развертывания службы вам понадобится веб-сервер/сервер приложений, такой как Tomcat, GlassFish или JBoss. Кроме того, мы будем использовать платформу jersey для создания конечной точки нашего сервиса. Обратите внимание, что для версии GlassFish 4.x требуются библиотеки jersey версии 2, поэтому, если вы используете GlassFish 4, используйте зависимости jersey 2.x. javatutorial.net/java-file-upload-rest-service - person Mallikarjuna; 26.10.2017
comment
Вместо этого вы можете отредактировать ответ;) извините, это модерация - person GGO; 26.10.2017
comment
как я могу сделать это без трикотажа или весны. без каких-либо аннотаций или специальных рамок. Я использую простые зависимости httphandler и maven. - person sns; 29.07.2018

Получение InputStream возможно в JAX-RS. Вы просто ставите параметр InputStream без аннотаций:

@POST
public void uploadImage(InputStream stream) {
    // store image
}

Обратите внимание, что это будет работать для любого типа контента.

Хотя это сработает, я бы предложил более «способ JAX-RS»:

1 Создайте провайдера, который создаст класс изображения (например, java.awt.Image) из InputStream:

@Provider
@Consumes("image/jpeg")
class ImageProvider implements MessageBodyReader<Image> {

    public Image readFrom(Class<Image> type,
                                Type genericType,
                                Annotation[] annotations,
                                MediaType mediaType,
                                MultivaluedMap<String, String> httpHeaders,
                                InputStream entityStream) throws IOException,
        WebApplicationException {
       // create Image from stream
    }
}

2. Зарегистрируйте провайдера так же, как вы регистрируете ресурс.
3. Настройте класс ресурсов для получения изображения вместо InputStream.

Почему этот подход лучше?
Вы отделяете логику десериализации от своего класса ресурсов. Так что если в будущем вы захотите поддерживать больше форматов изображений, вам просто нужно добавить дополнительных провайдеров, при этом ресурс останется прежним.

person Tarlog    schedule 20.04.2011
comment
Привет, Tarlog, для вашего первого метода, как бы вы отправили запрос на конечную точку? Будет ли InputStream параметром формы? Я использую клиент google rest для имитации запроса, и я не понимаю, как это проверить... - person c12; 27.04.2011
comment
@ c12: Извините, я не знаком с клиентом Google Rest. Но это должен быть не параметр формы, а тело запроса. С Wink Client это будет что-то вроде: new RestClient().resource(url).post(body), а body — OutputStream. - person Tarlog; 27.04.2011
comment
спасибо за быстрый ответ, я не думаю, что Rest Client его поддерживает. Я попробую то, что вы предложили, с HTTPClient, возможно, это сработает. - person c12; 27.04.2011
comment
для второго решения, возможно ли увеличить его, чтобы он также принимал параметры формы? - person c12; 27.04.2011
comment
извините за все вопросы, но как бы вы выполнили второе решение на основе контекста URL? Как почта сопоставляется с этим провайдером? - person c12; 27.04.2011
comment
Apache Wink (incubator.apache.org/wink) поддерживает написанный мной код, преимущества его использования : вы можете повторно использовать поставщиков JAX-RS. - person Tarlog; 27.04.2011
comment
Вы не можете получить InputStream в качестве параметра формы с JAX-RS. - person Tarlog; 27.04.2011
comment
›Как бы вы выполнили второе решение на основе контекста URL-адреса? Как почта сопоставляется с этим провайдером? - извините, но я не понимаю вопроса. Провайдер используется для сериализации/десериализации тела сообщения. Если вам нужен доступ для запроса информации, вы можете использовать @Context UriInfo. - person Tarlog; 27.04.2011
comment
@Tarlog Можете ли вы прислать мне пример? Пожалуйста, напишите мне на [email protected] - person Sudheer Kumar; 21.05.2013