做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;
}
}