java.io.IOException: Broken pipe

做1个接口,处理前端请求图片跨域的问题。由于前端拿图片的时候,有跨域问题,所以让后台先拿到图片,然后再写给前台。本来下面的代码没什么太大的问题,但是如果前台请求的图片一多(1个页面中有很多图片),有些请求就会报错:java.io.IOException: Broken pipe…

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

@Slf4j
@Service
public class FileServiceImpl implements IFileService {

    @Autowired
    private HttpServletResponse response;


    @Override
    public void getImg(String imageUrl) {

        URL target = null;
        
        try {

            target = new URL(imageUrl);

            URLConnection urlConnection = target.openConnection();

            //获取输入流
            InputStream inputStream = urlConnection.getInputStream();

            byte[] bytes = StreamUtils.copyToByteArray(inputStream);

            StreamUtils.copy(bytes, response.getOutputStream());

            response.getOutputStream().close();

        } catch (Exception e) {
            log.error("获取图片失败, 图片url: {}, 异常信息: {}", imageUrl, e);
        }

    }

}

因此,需要加上Content-Length响应头,由于没有告知客户端响应是否写完(当前返回的数据响应体大小),客户端就可能随时主动断开连接

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

@Slf4j
@Service
public class FileServiceImpl implements IFileService, ServletContextAware {

    @Autowired
    private HttpServletResponse response;

    private ServletContext servletContext;

    @Override
    public void getImg(String imageUrl) {

        URL target = null;
        try {

            target = new URL(imageUrl);

            URLConnection urlConnection = target.openConnection();

            response.setHeader("Content-Type",servletContext.getMimeType(imageUrl));

            //获取输入流
            InputStream inputStream = urlConnection.getInputStream();

            byte[] bytes = StreamUtils.copyToByteArray(inputStream);

            // 必须告诉浏览器客户端当前数据的大小, 否则客户端可能会断开连接, 导致broke pipe异常
            response.setContentLength(bytes.length);

            StreamUtils.copy(bytes, response.getOutputStream());

            response.getOutputStream().close();

        } catch (Exception e) {
            log.error("获取图片失败, 图片url: {}, 异常信息: {}", imageUrl, e);
        }

    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
}

你可能感兴趣的:(记录,java)