• java-后端调用第三方接口返回图片流给前端


    一、背景

    有个需求是这样的,客户端直接通过外网访问oss获取图片需要额外付费,考虑到成本问题,修改技术方案为:客户端将请求链接发给后端,后端根据请求做一定的截取或拼接,通过内网调用oss,再将下载下来的图片流返回给前端。

    图片流,展现在页面上就是直接返回一张图片在浏览器上。

    二、具体代码展示 

    前端期望,如果异常,直接把http status返回非200

    1. @Slf4j
    2. @RestController
    3. public class PictureController {
    4. @Autowired
    5. private PictureService pictureService;
    6. @RequestMapping(value = "getPicture")
    7. public void getPicture(String path, HttpServletResponse resp) {
    8. boolean picSuccess;
    9. // 注意:一定要有这步,否则图片显示不出来
    10. resp.setContentType(MediaType.IMAGE_JPEG_VALUE);
    11. long start = System.currentTimeMillis();
    12. try {
    13. picSuccess = pictureService.getOssPicture(path, resp);
    14. if (!picSuccess) {
    15. resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
    16. }
    17. } catch (Exception e) {
    18. resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
    19. log.error("下载图片失败!!");
    20. }
    21. log.info("cmd=/getPicture,param={},cost:{}", path, System.currentTimeMillis() - start);
    22. }
    23. }
    1. public interface PictureService {
    2. boolean getOssPicture(String path, HttpServletResponse resp) throws IOException;
    3. }
    1. @Slf4j
    2. @Service
    3. public class PictureServiceImpl implements PictureService {
    4. @Value("${alioss.ak}")
    5. private String accessKeyId;
    6. // http://*********.aliyuncs.com
    7. @Value("${url.prefix}")
    8. private String urlPrefix;
    9. @Value("${oss.connect.time:3000}")
    10. private int ossConnectTime;
    11. @Override
    12. public boolean getOssPicture(String path, HttpServletResponse resp) throws IOException {
    13. String url = getOssUrl(path);
    14. long st = System.currentTimeMillis();
    15. Request requestDownload = new Request.Builder()
    16. .url(url)
    17. .build();
    18. OkHttpClient client = new OkHttpClient();
    19. client = client.newBuilder().connectTimeout(ossConnectTime, TimeUnit.MILLISECONDS).build();
    20. Response responseDownload = client.newCall(requestDownload).execute();
    21. if (responseDownload.isSuccessful() && responseDownload.body() != null && responseDownload.body().byteStream() != null) {
    22. InputStream is = responseDownload.body().byteStream();
    23. writeImageFile(resp, is);
    24. } else {
    25. log.error("PictureServiceImpl-oss调用返回异常: url={}, data={}", url, responseDownload);
    26. return false;
    27. }
    28. long responseTime = System.currentTimeMillis() - st;
    29. log.info("request-oss cost:{}", responseTime);
    30. return true;
    31. }
    32. // base64解码==这块是与前端约定好的,我这边要做的解码
    33. private String getOssUrl(String path) throws UnsupportedEncodingException {
    34. final Base64.Decoder decoder = Base64.getDecoder();
    35. String decodePath = new String(decoder.decode(path), "UTF-8");
    36. StringBuffer buffer = new StringBuffer();
    37. String[] split = decodePath.split("&");
    38. for (int i = 0; i < split.length; i++) {
    39. if (!split[i].startsWith("Version")) {
    40. buffer.append(split[i]).append("&");
    41. }
    42. }
    43. log.info("getOssUrl={}", urlPrefix + buffer);
    44. buffer.append("OSSAccessKeyId=").append(accessKeyId);
    45. return urlPrefix + buffer;
    46. }
    47. /**
    48. * 将输入流输出到页面
    49. *
    50. * @param resp
    51. * @param inputStream
    52. */
    53. public void writeImageFile(HttpServletResponse resp, InputStream inputStream) {
    54. OutputStream out = null;
    55. try {
    56. out = resp.getOutputStream();
    57. int len = 0;
    58. byte[] b = new byte[1024];
    59. while ((len = inputStream.read(b)) != -1) {
    60. out.write(b, 0, len);
    61. }
    62. out.flush();
    63. } catch (IOException e) {
    64. e.printStackTrace();
    65. } finally {
    66. try {
    67. if (out != null) {
    68. out.close();
    69. }
    70. } catch (Exception e) {
    71. e.printStackTrace();
    72. }
    73. }
    74. }
    75. }

    三、总结

    上面就是返回图片流的方式;

    记录下!

  • 相关阅读:
    vue源码分析(一)——源码目录说明
    Simulink仿真中将工作空间中的数据变量保存成.mat文件
    【15-项目中服务的远程调用之OpenFeign&订单模块与商品模块集成使用OpenFeign的案例】
    神经网络示意图怎么画,ppt画神经网络模型图
    英伟达两个最新元宇宙布局
    PEG 衍生物Biotin-PEG1-OH(cas:95611-10-2,2-生物素氨基乙醇)优势说明
    二维码智慧门牌管理系统:强化地址管理,推动政府业务协同
    使用@Builder注解后,该对象 拷贝时出现java.lang.InstantiationException异常报错
    85.(cesium之家)cesium模型在倾斜摄影上运动
    基于jsp+Spring boot+mybatis的图书管理系统设计和实现
  • 原文地址:https://blog.csdn.net/weixin_40618648/article/details/134054672