若依框架,小程序访问后端,后端访问客户端,客户端读取图片返回

服务端代码:

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;

@Controller
@RequestMapping("/api")
public class ImageController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/get-image")
    public ResponseEntity<InputStreamResource> getImage(@RequestParam String identifier, @RequestParam String path) {
        // 构建客户端请求URL
        String clientUrl = "http://client-server/api/fetch-image?identifier=" + identifier + "&path=" + path;
        
        // 通过RestTemplate调用客户端接口
        ResponseEntity<byte[]> response = restTemplate.getForEntity(clientUrl, byte[].class);

        if (response.getStatusCode() == HttpStatus.OK) {
            // 将客户端返回的图片数据封装到InputStreamResource中
            InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(response.getBody()));
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "image/png");
            
            return new ResponseEntity<>(resource, headers, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

客户端代码:

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

@Controller
@RequestMapping("/api")
public class ClientImageController {

    @GetMapping("/fetch-image")
    public ResponseEntity<byte[]> fetchImage(@RequestParam String identifier, @RequestParam String path) {
        // 构建图片文件的完整路径
        String fullPath = "/path/to/images/" + identifier + path;

        try {
            // 打开图片文件的输入流
            InputStream inputStream = new FileInputStream(fullPath);
            
            // 读取图片数据
            byte[] imageData = inputStream.readAllBytes();
            inputStream.close();

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "image/png");
            
            return new ResponseEntity<>(imageData, headers, HttpStatus.OK);
        } catch (IOException e) {
            // 处理文件未找到或其他IO异常
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

说明

  1. 服务端

    • 使用 RestTemplate 调用客户端的接口。
    • 将客户端返回的图片数据封装到 InputStreamResource 中,并返回给前端。
  2. 客户端

    • 接收服务端的请求,读取本地图片文件。
    • 将图片数据以字节数组的形式返回给服务端。

配置

  1. RestTemplate Bean(在服务端的配置类中添加):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2.图片路径:根据你的实际情况修改 fullPath 的前缀路径,以适应你的图片存储路径。

这个示例代码展示了如何在服务端调用客户端读取本地图片并返回给前端的基本流程。如果需要处理更多的业务逻辑或错误情况,可以进一步完善代码。

在实现通过后端接口调用后自动触发前端下载 Excel 文件的功能时,需要从前端和后端两个角度进行设计和开发。以下是完整的实现方式: ### 前端实现 前端需要通过 HTTP 请求(如 `axios`)向后端发起请求,并处理返回的文件流。为了实现自动下载,前端需要将响应类型设置为 `blob`,然后通过创建临时的 `<a>` 标签并触发点击事件来实现文件下载。 以下是一个完整的 Vue 前端示例代码: ```javascript import axios from 'axios'; methods: { downloadExcel() { const params = { // 传递给后端的参数 startDate: '2023-01-01', endDate: '2023-12-31' }; axios({ method: 'post', url: 'http://your-api-endpoint.com/export-excel', data: params, responseType: 'blob' // 必须设置为 blob 类型 }).then(response => { // 创建 Blob 对象,指定类型为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 创建临时下载链接 const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', 'exported-data.xlsx'); // 设置下载文件名 document.body.appendChild(link); link.click(); // 触发下载 // 清理临时链接 window.URL.revokeObjectURL(url); document.body.removeChild(link); }).catch(error => { console.error('导出 Excel 文件失败:', error); }); } } ``` ### 后端实现 后端需要根据请求生成 Excel 文件,并将文件流以二进制格式返回。不同的后端语言有不同的库支持生成 Excel 文件,例如 Python 的 `openpyxl` 或 `pandas`,Node.js 的 `exceljs` 等。 以下是一个使用 Python(Flask 框架)的后端示例: ```python from flask import Flask, request, send_file from openpyxl import Workbook import io app = Flask(__name__) @app.route('/export-excel', methods=['POST']) def export_excel(): # 获取前端传递的参数 data = request.json start_date = data.get('startDate') end_date = data.get('endDate') # 生成 Excel 文件 wb = Workbook() ws = wb.active ws.title = "Data" ws.append(["日期", "数据"]) # 添加表头 ws.append([start_date, "示例数据1"]) ws.append([end_date, "示例数据2"]) # 将 Excel 文件写入内存中的 BytesIO 对象 file_stream = io.BytesIO() wb.save(file_stream) file_stream.seek(0) # 返回文件流作为响应 return send_file( file_stream, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', as_attachment=True, download_name='exported-data.xlsx' ) ``` ### 注意事项 - **响应头设置**:后端返回文件流时,必须设置正确的 `Content-Type`,如 `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,以确保前端能正确识别为 Excel 文件。 - **文件名设置**:后端可以通过 `Content-Disposition` 头指定文件名,或者前端在创建 `<a>` 标签时手动指定下载文件名。 - **跨域问题**:如果前端和后端不在同一个域名下,需要在后端配置 CORS 支持,并允许 `Content-Type` 和 `Content-Disposition` 等必要的响应头。 - **错误处理**:前端和后端都需要处理可能的错误情况,例如参数缺失、权限不足、生成文件失败等。 通过上述前后端配合,可以实现在调用后端接口后自动触发 Excel 文件的下载功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值