开发背景

系统要对接飞鹅云打印机进行打印,需要通过指定接口打印数据
因为使用SpringBoot开发,刚好用RestTemplate+postForObject发送POST请求并接受结果。

设置请求头(Content-Type)

接口要求请求头中要带Content-Type: application/x-www-form-urlencoded

思路:
先创建个实现ClientHttpRequestInterceptor接口的类,在intercept(…)方法中对请求头设置,在使用RestTemplate的时候设置或添加这个Interceptor类,然后再发送请求

MyPostInterceptor类:

@Component
public class MyPostInterceptor implements ClientHttpRequestInterceptor {private Logger logger = LoggerFactory.getLogger(this.getClass());//设置默认请求头为application/x-www-form-urlencodedprivate MediaType mediaType = MediaType.APPLICATION_FORM_URLENCODED;/***参考链接https://www.cnblogs.com/yihuihui/p/13211699.html*/@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {//设置请求头request.getHeaders().setContentType(mediaType);//另一种设置方法
//        request.getHeaders().add("Content-Type",MediaType.APPLICATION_FORM_URLENCODED_VALUE);logger.info("===request: {}, {}, {}", request.getURI().getHost(), request.getURI().getPath(),request.getHeaders());logger.info("===requestBody: {}", new String(body,UTF_8));return execution.execute(request, body);}//Get/Set忽略
}

发送请求:

 //myPostInterceptor自动注入省略...//构建数据实体类feiEPrintBody...RestTemplate restTemplate = new RestTemplate();//设置请求类型,NORMAL_HEADER=MediaType.APPLICATION_FORM_URLENCODEDmyPostInterceptor.setMediaType(NORMAL_HEADER);restTemplate.setInterceptors(Collections.singletonList(myPostInterceptor));//另一种设置方法
//  restTemplate.getInterceptors().add(myPostInterceptor);//增加返回消息转换类,详见下方踩坑1restTemplate.getMessageConverters().add(new PostMappingJackson2HttpMessageConverter());//提交数据并获取结果,这里也有坑,详见踩坑2//OPEN_API为接口网址JSONObject result = restTemplate.postForObject(OPEN_API,feiEPrintBody.builderMultiValueMap(),JSONObject.class);

踩坑1

RestTemplate的默认处理响应类型为application/json,但接口返回数据格式为text/html,RestTemplate无法转换信息报错:UnknownContentTypeException

org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.alibaba.fastjson.JSONObject] and content type [text/html;charset=UTF-8]at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126)...

解决:给RestTemplate增加一个处理指定响应数据类型的HttpMessageConverter
这里知道接口返回的是json格式,所以这里继承spring中默认的MappingJackson2HttpMessageConverter

/*** POST返回信息 TEXT_HTML转换类* 参考https://blog.csdn.net/kinginblue/article/details/52706155*/
public class PostMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {public PostMappingJackson2HttpMessageConverter(){List<MediaType> mediaTypes;mediaTypes = new ArrayList<>();//设置消息转换类的响应类型mediaTypes.add(MediaType.TEXT_HTML);setSupportedMediaTypes(mediaTypes);}
}

踩坑2

设置请求头后,一开始使用以下方式发送数据,接口报错,一开始以为是请求头设置没有生效找了半天

//feiEPrintBody为pojo
JSONObject result = restTemplate.postForObject(OPEN_API,feiEPrintBody,JSONObject.class);


后面经群友提示,application/x-www-form-urlencoded不能传json格式的body,排查后发现,直接传对象会被RestTemplate转为json格式,修改后才解决

解决:改用LinkedMultiValueMap存字段
Tip:必须要使用LinkedMultiValueMap,用MultiValueMap仍有转为Json的问题
这里直接在存数据类里加个新建方法,然后在发送方法里调用

 //FeiEPrintBody构建传值mappublic MultiValueMap builderMultiValueMap() {LinkedMultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();postParameters.add("user", getUser());postParameters.add("stime", getStime());postParameters.add("sig", getSig());postParameters.add("apiname", getApiName());postParameters.add("sn", sn);postParameters.add("content", content);if (times > 0) {postParameters.add("times", String.valueOf(times));}if (img != null) {postParameters.add("img", img);}return postParameters;}
//OPEN_API为接口网址
JSONObject result = restTemplate.postForObject(OPEN_API,feiEPrintBody.builderMultiValueMap(),JSONObject.class);

设置后提交的Body变化了,接口调用成功

解决后吐槽:快乐撸码五分钟,苦逼Debug两小时

SpringBoot项目使用RestTemplate发送请求踩坑记录相关推荐

  1. 微信客服机器人(踩坑记录、SpringBoot、企业微信)

    微信客服机器人(踩坑记录.SpringBoot.企业微信) 转载请注明出处:https://www.jjput.com/archives/wei-xin-ke-fu-ji-qi-ren 总体流程 当有 ...

  2. uc浏览器请求被拦截报跨域踩坑记录

    记录下开发时uc浏览器请求被拦截时遇到的问题 请求在uc浏览器出现跨域问题 app使用uniapp开发,使用plus.runtime.launchApplication来打开并跳转指定页面,并在Xco ...

  3. SpringBoot踩坑记录 Invalid bound statement (not found)引发的一些列问题

    SpringBoot踩坑记录 Invalid bound statement (not found)引发的一些列问题 当你开开心心搭建了一个SpringBoot项目,用插件生成了entity.dao. ...

  4. RestTemplate 发送请求 清除Cookie

    RestTemplate 发送请求时 Cookie 的影响及注意事项 背景 ​ 一个基于 SpringCloud 的多服务项目中,服务间调用通过 Spring 的 RestTemplate 实现,后台 ...

  5. SpringBoot踩坑记录--Invalid bound statement (not found): com.zxq.crud.dao.UserDao.selectAllByDepart

    SpringBoot踩坑记录--Invalid bound statement: com.zxq.crud.dao.UserDao.selectAllByDepart 运行SpringBoot项目时提 ...

  6. 记SpringBoot项目运行2h自动挂掉的坑

    记SpringBoot项目运行2h自动挂掉的坑 背景 过程 解决方案一 解决方案二 总结 背景 以前多使用tomcat容器部署war项目或者使用jenkins直接部署,没有亲自体验过部署jar.所以, ...

  7. 配合Opencv2.4.9,CMake3.12.1和VS2010在win10下构建项目踩坑记录

    配合Opencv3,CMake和VS2010在win10下构建项目踩坑记录 参考https://blog.csdn.net/qq_26623659/article/details/78322782 博 ...

  8. vue项目中将视频链接分享至推特的解决方法及踩坑记录

    vue项目中将视频链接分享至推特的解决方法及踩坑记录 将动态改变的视频链接分享至推特,并希望能直接在推特上播放视频的需求实现方法及踩坑记录 如果只要将文本或链接分享到推特,不需要推特识别图片/视频等媒 ...

  9. 记一次成功把Vue2后台项目改造成Vite2的踩坑经历

    文章目录 前言 一.项目背景 1.1.为什么要选择Vite 二.迁移前的准备 2.1.补全.vue后缀 2.2.移动public/index.html的位置 2.2.1.通过vite-plugin-h ...

  10. 日常踩坑记录-汇总版

    开发踩坑记录,不定时更新 心得 RTFM 严谨的去思考问题,处理问题 严格要求自己的代码编写习惯与风格 注意 单词拼写 20200207 mybatis plus 自带insert插入异常 sql i ...

最新文章

  1. OpenCV寻找复杂背景下物体的轮廓
  2. Laravel-自定全局函数
  3. 【Linux 内核 内存管理】RCU 机制 ③ ( RCU 模式下添加链表项 list_add_rcu 函数 | RCU 模式下删除链表项 list_del_rcu 函数 )
  4. java 8 parallelStream()
  5. 关于ESP8266 GPIO中断使用的总结
  6. PsSetCreateProcessNotifyRoutineEx进程监控框架
  7. 计算机绘图cg,CG专业英语整理
  8. 视频流中的DTS、PTS到底是什么
  9. jsp页面获取系统的日期时间
  10. [译]快照技术综述 Ⅰ
  11. Java 和C# 最大的不同是对底层的控制能力不同
  12. BGP安全特性(华为设备)
  13. java自己写框架_用java自己动手写个简单RCP框架
  14. web前端开发培训培训,JavaScript运算符
  15. android 微信朋友圈动画,使用Android 模仿微信朋友圈图片拖拽返回
  16. C++横板格斗小游戏(基于Easyx图形库)
  17. linux mint19内核,aria2的Linux Mint 19安装过程完整总结
  18. Miktex安装宏包
  19. [XUPT]2020寒假训练---比赛专题
  20. VBS脚本实现宽带上网加网页认证上网双验证

热门文章

  1. Tivoli基础架构管理解决方案
  2. SSH-keygen用法
  3. Dev-C++中, “\“反斜杠符号显示成人民币符号、中文斜躺 问题
  4. 云计算与大数据概论(二)
  5. 设置名字的第一个字为默认头像
  6. Spring Mvc - 用户注册服务端生成默认头像实现
  7. Ubuntu 20.04 桌面美化
  8. 使用backdrop-filter部分场景的替代效果
  9. HiWork告诉你:拿什么来拯救你,我的时间
  10. bzoj2555 SubString (SAM+LCT维护子树大小/ETT)