0. 前言
前端服务器是https协议,B组图片服务器是http协议
业务配合,前端服务器不能使用https请求B组图片服务器,后端服务器可以使用http请求B组服务器,故需要在后端服务器进行一次包装,把图片以流的形式返回给前端
1.控制层
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
/**
* @author wenwen
* @DATE: 2020/12/14
**/
@Slf4j
@Controller //因为是直接使用流的形式响应所以不能用@RestController
@RequestMapping("api")
public class StoreImgTurnController {
@Autowired
IService iService;
@ApiOperation("请请求图片包层连接")
@ApiImplicitParam(value = "图片地址",name = "storeImg",required = true,dataType = "String",paramType = "query")
@GetMapping("/getImgFile")
public void getImgFile(HttpServletRequest request , HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
String imgStr = request.getParameter("img");
if(StringUtils.isBlank(imgStr)){
response.sendError(403,"图片地址为空!");
return;
}
//获取所有的请求参数,处理图片中带&符号,把他拼接到storeImg上
Enumeration paramNames = request.getParameterNames();
StringBuilder img = new StringBuilder(imgStr);
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length >0) {
String paramValue = paramValues[0];
if (paramValue.length() != 0) {
if(!"img".equals(paramName)){
img.append("&")
.append(paramName)
.append("=")
.append(paramValue);
}
}
}
}
//获取输入流
InputStream str = iService.getImgFile(storeImg.toString());
if(str == null){
response.sendError(402,"图片获取失败,请核对传入参数!");
return;
}
String ext = "JPG";
//获取文件后缀名格式
if(storeImg.toString().contains(".")){
ext = storeImg.substring(storeImg.indexOf(".")).toUpperCase();
}
//判断图片格式,设置相应的输出文件格式
if(ext.equals("JPG")){
response.setContentType("image/jpeg;charset=UTF-8");
}else if(ext.equals("PNG")){
response.setContentType("image/png;charset=UTF-8");
}else{
response.setContentType("image/jpeg;charset=UTF-8");
}
//获取输出流
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
//创建存放文件内容的数组
byte[] buff =new byte[1024];
//所读取的内容使用n来接收
int n;
//当没有读取完时,继续读取,循环
while((n=str.read(buff))!=-1){
//将字节数组的数据全部写入到输出流中
outputStream.write(buff,0,n);
}
response.setHeader("Content-Disposition", "inline; filename=\"" + storeImg + "\"");
//强制将缓存区的数据进行输出
outputStream.flush();
//关流
outputStream.close();
if(log.isInfoEnabled()){
log.info("响应完成!");
}
}
}
2.服务层
@Override
public InputStream getImgFile(String img) {
if(log.isInfoEnabled()){
log.info("本次请求地址:"+img);
}
//请求流
return getInputStream(img);
}
/**
* 获得服务器端数据,以InputStream形式返回
*
* @return 请求流
* @throws IOException 请求失败响应
*/
public static InputStream getInputStream(String img) {
InputStream inputStream = null;
HttpURLConnection httpURLConnection = null;
try {
URL url = new URL(img);
if (url != null) {
httpURLConnection = (HttpURLConnection) url.openConnection();
// 设置连接网络的超时时间
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setDoInput(true);
// 设置本次http请求使用get方式请求
httpURLConnection.setRequestMethod("GET");
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == 200) {
// 从服务器获得一个输入流
inputStream = httpURLConnection.getInputStream();
}
}
} catch (IOException e) {
e.printStackTrace();
}
return inputStream;
}
3.注意
- 请求B组文件时以流的形式接收
- 后端服务器响应时要设置对应图片响应格式
response.setContentType("image/jpeg;charset=UTF-8");
- 接收的参数里含有链接,要正常转换,注意处理内含链接中的&
躬身自省,淳朴而谦逊否——文文的博客
前辈见之,如有问题,麻烦留言斧正。