且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从URL读取InputStream并由Servlet编写

更新时间:2023-12-04 15:46:29

我试图对您的代码进行一些修改,以解决getResponseCode()connect()的错误顺序以及其他一些小问题. /p>

特别是如果出现问题(例如,在其他服务器上找不到文件,IOException,非法URL等),请务必始终返回错误状态代码(不是2xx),否则浏览器始终会显示200-可以,但是没有数据!

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String requestedUrl = request.getParameter("url");

    if (StringUtils.isBlank(requestedUrl)) {
        // TODO: send error code 400 - Bad Request
        return;
    }

    try {
        URL url = new URL(requestedUrl);
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
        response.setContentType("image/jpg");
        httpConnection.connect();

        int responseCode = httpConnection.getResponseCode();

        if (responseCode == HttpURLConnection.HTTP_OK) {
            // TODO: set correct content type to response

            OutputStream outputStream = response.getOutputStream();

            try (InputStream imageStream = url.openStream()) {
                IOUtils.copy(imageStream, outputStream );
            }
        } else {
            // TODO: send error code (depends on responseCode), probably 500
        }
    } catch (Exception ex) {
        Log.error(this, ex.getMessage(), ex);
        // TODO: send error code 400 if malformed url
        // TODO: send error code 404 if image not found (responseCode == 404)
        // TODO: send error code 500 else
    }
    // Don't close the response-OutputStream! You didn't open it either!
}

I am trying to write an InputStream, which I get from an URL by the doGet method of Servlet. Here is my code:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String requestedUrl = request.getParameter("url");

    if (StringUtils.isNotBlank(requestedUrl)) {
        ReadableByteChannel inputChannel = null;
        WritableByteChannel outputChannel = null;

        try {
            URL url = new URL(requestedUrl);
            HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
            int responseCode = httpConnection.getResponseCode();

            System.out.println(responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                response.setContentType("image/jpg");
                httpConnection.connect();
                InputStream imageStream = url.openStream();
                OutputStream outputStream = response.getOutputStream();

                inputChannel = Channels.newChannel(imageStream);
                outputChannel = Channels.newChannel(outputStream);
                ByteBuffer buffer = ByteBuffer.allocate(10240);

                while (inputChannel.read(buffer) != -1) {
                    buffer.flip();
                    outputChannel.write(buffer);
                    buffer.clear();
                }
            }
        } catch (Exception ex) {
            Log.error(this, ex.getMessage(), ex);
        } finally {
            if (ObjectUtils.notEqual(outputChannel, null)) {
                try {
                    outputChannel.close();
                } catch (IOException ignore) {
                }
            }

            if (ObjectUtils.notEqual(inputChannel, null)) {
                try {
                    inputChannel.close();
                } catch (IOException ignore) {
                }
            }
        }
    }
}

I can see in console that the responseCode is 200 but it is not writing anything in the page. In Firefox I am getting:

The image "the_context_root/dam/no-image-aware-servlet?url=http%3A//localhost%3A80/file/MHIS044662&Rendition=164FixedWidth&noSaveAs=1" cannot be displayed because it contains errors.

I am unable to find what I am doing wrong. Any pointer would be very helpful.

I've tried to modify your code a little bit to address the wrong order of getResponseCode() and connect() as well as some other minor issues.

Especially make sure to ALWAYS return an error status code (other than 2xx) if something goes wrong (e.g. file not found on other server, IOException, illegal URL, ...), otherwise the browser always gets 200 - OK but no data!

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String requestedUrl = request.getParameter("url");

    if (StringUtils.isBlank(requestedUrl)) {
        // TODO: send error code 400 - Bad Request
        return;
    }

    try {
        URL url = new URL(requestedUrl);
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
        response.setContentType("image/jpg");
        httpConnection.connect();

        int responseCode = httpConnection.getResponseCode();

        if (responseCode == HttpURLConnection.HTTP_OK) {
            // TODO: set correct content type to response

            OutputStream outputStream = response.getOutputStream();

            try (InputStream imageStream = url.openStream()) {
                IOUtils.copy(imageStream, outputStream );
            }
        } else {
            // TODO: send error code (depends on responseCode), probably 500
        }
    } catch (Exception ex) {
        Log.error(this, ex.getMessage(), ex);
        // TODO: send error code 400 if malformed url
        // TODO: send error code 404 if image not found (responseCode == 404)
        // TODO: send error code 500 else
    }
    // Don't close the response-OutputStream! You didn't open it either!
}