Hutool的HttpUtil实现调用POST表单接口上传文件

1、客户端代码

private String uploadWithHutool(InputStream inputStream, String channelCode) {
        if (inputStream == null) {
            log.error("文件输入流为空,无法上传");
            return null;
        }

        DateTime date = DateUtil.date();
        String dateTime = DateUtil.formatDateTime(date);

        String fileName = "漳潭360" + dateTime + ".png";

        InputStreamResource inputStreamSource;
        try {
            inputStreamSource = new InputStreamResource(inputStream, fileName);
        } catch (Exception e) {
            log.error("文件输入流转换为InputStreamResource失败", e);
            return null;
        }

        try (HttpResponse response = HttpUtil.createPost(pictureSaveUrl)
                .header("Content-Type", "multipart/form-data")
                // 设置表单参数(文件),第一个参数为接口接收的参数名(如"file")
                .form("file", inputStreamSource)
                // 可选:添加其他表单参数(如果接口需要)
                .form("channelCode", channelCode)
                // 执行请求
                .execute()) {
            // 获取响应体(根据接口返回格式调整,如JSON/文本)
            return response.body();
        } catch (Exception e) {
            log.error("截图文件上传失败", e);
            return null;
        }
    }

2、服务端接口代码

    @PostMapping("/add")
    @ApiOperation("视频截图保存接口")
    public Result<String> add(@Valid @RequestBody VideoPictureAddPO po) throws IOException {
        String pictureId = videoDevicePictureService.addVideoPicture(po);
        return Result.success(pictureId);
    }
@Data
public class VideoPictureAddPO {

    /**
     * 视频通道code,d_video_device
     */
    @NotBlank(message = "视频通道code不能为空")
    private String channelCode;

    /**
     * 截图附件
     */
    @NotNull(message = "截图附件不能为空")
    private MultipartFile file;

}
@Override
    public String addVideoPicture(VideoPictureAddPO addPO) {
        log.info("addVideoPicture addPO:{}", addPO);
        String channelCode = addPO.getChannelCode();
        MultipartFile file = addPO.getFile();

        LambdaQueryWrapper<DVideoDeviceDO> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(DVideoDeviceDO::getChannelCode, channelCode);
        DVideoDeviceDO deviceDO = videoDeviceMapper.selectOne(lambdaQueryWrapper);

        Assert.notNull(deviceDO, buildBaseException(ARGUMENT_NOT_VALID, "摄像头不存在"));

        DateTime date = DateUtil.date();
        String dateTime = DateUtil.formatDateTime(date);

        String fileName = deviceDO.getStationName() + dateTime + ".png";

        Tuple tuple = attachmentService.uploadAttachmentWithoutAuthInfo("env-water-ecological", fileName, file);

        DVideoDevicePictureDO pictureDO = new DVideoDevicePictureDO();
        pictureDO.setId(IdUtil.getSnowflakeNextIdStr());
        pictureDO.setEnterpriseCode(deviceDO.getEnterpriseCode());
        pictureDO.setStationCode(deviceDO.getStationCode());
        pictureDO.setStationName(deviceDO.getStationName());
        pictureDO.setChannelCode(deviceDO.getChannelCode());
        pictureDO.setAttachmentId(tuple.get(0));
        pictureDO.setAttachmentName(fileName);
        pictureDO.setDataTime(date);
        this.save(pictureDO);

        return pictureDO.getId();
    }

结论:重点在于InputStreamResource转换输入流,以及httpUtil的post请求的header一定要加上.header("Content-Type", "multipart/form-data")

posted @ 2025-08-20 17:50  云翊宸  阅读(667)  评论(0)    收藏  举报