【问题标题】:Create Rest Web Service to receive an Image创建 Rest Web 服务以接收图像
【发布时间】:2011-04-19 20:37:53
【问题描述】:

您将如何设计一个基于 REST 的 Web 服务,它以InputStream 的形式接收图像文件?如果InputStream 发布到 REST 端点,该端点如何接收它以便创建图像文件?

【问题讨论】:

    标签: java rest jax-rs resteasy


    【解决方案1】:

    在 JAX-RS 中可以接收 InputStream。您只需将 InputStream 参数不带注释:

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

    注意它适用于任何内容类型。

    虽然它会起作用,但我会建议一种更“JAX-RS 方式”:

    1 创建将从 InputStream 创建图像类(例如 java.awt.Image)的提供程序:

    @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 让您的资源类接收 Image 而不是 InputStream。

    为什么这种方法更好?
    您将反序列化逻辑与资源类分开。因此,如果将来您想支持更多的图像格式,您只需要添加额外的提供程序,而资源将保持不变。

    【讨论】:

    • 嗨 Tarlog,对于您的第一种方法,您将如何将请求发送到端点? InputStream 会是表单参数吗?我正在使用 google rest 客户端来模拟一个请求,但我不明白如何测试这个......
    • @c12:抱歉,我不熟悉 Google Rest Client。但它不应该是一个表单参数,而是一个请求体。使用 Wink 客户端,它类似于:new RestClient().resource(url).post(body),而 body 是 OutputStream。
    • 感谢您的快速回复,我认为 Rest Client 不支持它。我会尝试你对 HTTPClient 的建议,也许会奏效..
    • 对于第二种解决方案,是否可以对其进行扩充,使其也接受表单参数?
    • 抱歉所有问题,但是您将如何根据 url 上下文执行第二个解决方案?帖子如何映射到该提供商?
    【解决方案2】:

    接收图像的示例 REST Web 服务 Java 类

    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();
            }
    }
    }
    

    【讨论】:

    • 我们希望得到一些解释
    • 文件通过 HTTP POST 以编码类型“multipart/form-data”从客户端推送到我们的 Web 服务。这样,除了文件之外,您还可以向 POST 请求添加多个参数。让我们从需求开始。您将需要一个 Web/应用程序服务器,如 Tomcat、GlassFish 或 JBoss 来部署该服务。此外,我们将使用 jersey 框架来构建我们的服务端点。请注意,GlassFish 4.x 版本需要 jersey 版本 2 库,因此如果您使用的是 GlassFish 4,请使用 jersey 2.x 依赖项。 javatutorial.net/java-file-upload-rest-service
    • 您可以改为编辑答案;)抱歉,这是审核
    • 没有 Jersey 或 spring 怎么办。没有任何注释或特殊框架。我使用普通的 httphandler 和 maven 依赖项。
    猜你喜欢
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多