RestTemplate
Posted on
最近做一个关于设计个人博客的项目实训,其中需要实现上传照片功能,思考再三,觉得保存在本地着实很 low,于是选择上传到第三方图床。接下来的问题很明确,如何调用第三方接口,首先想到的是大名鼎鼎的 HTTPClient,但 Spring 封装了库,提供了更为简洁的资源请求方式 RestTemplate。
API 接口
查看第三方图床 API 文档,上传图片为 POST 方法,参数暂时只需 File。


请求 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| private String uploadViaSmms(MultipartFile file) {
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
String requestUrl = "https://sm.ms/api/upload";
MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>(); postParameters.add("smfile", file.getResource());
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(postParameters, headers); ResponseEntity<String> response = restTemplate.postForEntity(requestUrl, requestEntity, String.class);
return response.getBody(); }
|
处理 JSON 数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Result r = new Result(); String result = uploadViaSmms(file);
JsonObject jsonObject = new JsonParser().parse(result).getAsJsonObject(); String code = jsonObject.get("code").getAsString(); if(!code.equals("success")) { r.setResultCode(ResultCode.UPLOAD_ERROR); return r; } String url = jsonObject.get("data").getAsJsonObject().get("url").getAsString(); String deleteUrl = jsonObject.get("data").getAsJsonObject().get("delete").getAsString();
imageService.upload(url, deleteUrl, description); r.setResultCode(ResultCode.SUCCESS);
return r;
|
需要注意的问题
- 如果 headers 不添加 user-agent,则会报 403 Forbidden,也算一种常见的反爬措施。

- file 类型必须是可序列化元素,只能使用
file.getResource()
,不能使用file.getBytes()
或file.getInputStream()
,否则会报 No serializer found。

↑这个问题困扰了我两天,晚上 4 点都睡不着都是因为这,コノヤロー!
参考资料
- 403 Forbidden
- parse JSON