记一个应届毕业生第一次编写接口代码的成长
2021年7月6日,我的第一个接口任务来了。
接口需求:为公司的一个连云港项目写两个接口,将原先存储在连云港项目数据库的人员考勤信息和工作人员信息每天定时推送到一个中间数据库中。
即:从项目数据库postgresql中定时读取数据,再插入到中间数据库mysql中。
接口的业务逻辑非常简单,甚至算不上增删改查,只涉及到查询和插入而已,但没想到这简单的两个需求,竟整整花了我一周的时间才完成,期间还少不了不停地请教隔壁先进入公司的后端同事。
***一、双数据源?***
公司的项目是当下最主流的SpringBoot项目,所以即使作为刚刚毕业的新手也算的上可以为公司编写代码,在同事的告知下我明白了需求,并且采纳了同事配置双数据源的建议。
从需求上可以发现,第一个对于新手的我来说,棘手的点就在于这个业务同时涉及到了mysql和我并不熟悉的postgres两个数据库,通过查询资料,我写了一个SpringBoot的小Demo来测试postgres和mysql
双数据源的使用,经过整整一天的coding,终于在自己的工程将测试demo跑通,效果为可以从postgres的数据库表中查询数据,并且插入mysql的数据库表中,至此,虽然涉及到了没用过的配置,但接口的进展
还算顺利。
***二、@Scheduled?***
通过一上午的逻辑编写和字段对应,我向同事提出了疑问,如何定时调用我所写的两个接口?同事在项目代码中找到了一个MainTask类,原来这个类是专门写定时服务的,其中的所有函数都加上了一个Spring
的注解:@Scheduled。通过该注解,可以指定每天或每月甚至每秒定时调用某服务,函数中需要开启线程,但类中有示例,实现也算简单。
***三、HttpUtils?***
在第二天的下午,实现所有业务逻辑代码后我在本地进行测试,但谁知在Demo中配置正确的双数据源,在公司的项目上却一直报错,从postgres数据库中查到数据后本来应该切换成第二个数据源去mysql中的表
中插入数据,谁知配置在此时不起作用,数据源并没有切换,报错一直提示在postgres中找不到插入时的表,当然找不到了,那个表在mysql的数据库中。又经过整整一天的折腾,双数据源不切换的bug还是没有在项目
上解决。此时已是第三天的下午。去请教同事,但可惜多数据源的配置他也没有用过,于是讨论后决定更换策略,不再使用双数据源配置,而是在保持公司的项目使用postgres数据库查询数据的时候,启动一个新的依赖
服务来插入数据,依赖的服务使用mysql数据库即可,这样就避免了配置多数据源,多数据源的坑实在太多。两个SpringBoot项目通过一个HttpUtils类来通信,定时调用主项目的查询并发送json数据字符串到依赖项目中,
由依赖项目的controller执行插入数据操作。
***四、打包过程***
经历了一天的重构,第四天终于在本地将测试服务跑通了,数据终于从postgres数据库通过依赖服务插入到了mysql数据库中,但是我没有打包部署项目的经验,于是在同事的指导下,将两个项目分别打包,通过远程
向日葵屏幕控制进行部署。新写的依赖服务是jar包,放在桌面上写个run.bat脚本即可;老项目则是war包打包方式,需要将改动的文件夹进行替换,如果替换lib包则需要把其中的tomcat相关的jar包删除掉。
***五、乱码问题***
然而在服务器上调用服务时,在老项目的黑窗口中的数据还是正常的,但在依赖服务中的中文数据却变成了????,插入数据库后更是变成了乱码,这个乱码问题足足困扰了我两天,最后终于找出问题根源所在。问
题出在我调用的HttpUtils类上,我以为这个类是以前开发写的,应该没问题,但最后证明,他只设置了input流的编码格式,没有设置output流的编码格式,导致了最终的乱码问题,将output输出流的编码指定为UTF-8后问题迎刃而解。
***总结***
历时五天的接口开发让我收获了很多,尤其是心态方面,出了问题一定要相信自己,多查多问,多向同事寻求帮助,经历了此次开发,我也学习到了后端的很多实际操作问题,例如部署前最好先备份一下,以免误操作将
服务器弄崩,开发很注重细节,一定不能急,哪怕没有进展也比制造bug强得多,一定要三思而行,多思考,谋定而后动。
附录:HttpUtils类最终版
public class HttpUtils { public static String doPost(String URL,String jsonStr){ DataOutputStream out = null; //OutputStreamWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); HttpURLConnection conn = null; try{ URL url = new URL(URL); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); //发送POST请求必须设置为true conn.setDoOutput(true); conn.setDoInput(true); //设置连接超时时间和读取超时时间 conn.setConnectTimeout(300000); conn.setReadTimeout(100000); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Accept", "application/json"); conn.setRequestProperty("Accept-Charset", "utf-8"); // conn.setRequestProperty("contentType", "GBK"); //获取输出流 out = new DataOutputStream(conn.getOutputStream()); //out = new OutputStream(conn.getOutputStream()); out.write(jsonStr.getBytes("utf-8")); // out.writeBytes(jsonStr) //out.write(jsonStr); out.flush(); out.close(); //取得输入流,并使用Reader读取 if (200 == conn.getResponseCode()){ in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null){ result.append(line); System.out.println(line); } }else{ System.out.println("ResponseCode is an error code:" + conn.getResponseCode()); } }catch (Exception e){ e.printStackTrace(); }finally { try{ if(out != null){ out.close(); } if(in != null){ in.close(); } }catch (IOException ioe){ ioe.printStackTrace(); } } return result.toString(); }