前言

在前后端交互的选择上,之前一直采用的是模板引擎(因为我只负责后端)。
而这次的一个算是作业吧,前后端都是我,所以就研究了一下JSON交互在java web的应用(主要是前端)。

优缺点

  • 前后端耦合

    • 模板引擎加载只是将jsp的交互方式移植到html上,前端文件格式改变了,但是jsp中前后端耦合的缺点没有改变。
    • json交互中,数据通过js/jquery动态加载在页面上,数据与页面进行分离,页面只是单纯用于展示。
  • 数据加载逻辑复用

    • 模板引擎的方式中,如果有很多相似的页面元素以及一样的数据返回格式,那只是复制粘贴大法了。
    • 在模板引擎的例子中,只需要定义一套数据加载模型,传入不同的页面元素id以及数据则能实现逻辑复用
  • 后端接口的复用
    因为我的学习路线的问题,所以我开发过安卓原生一段时间。

    • 模板引擎式的加载必须使用webView组件加载,且需另进行原生构建时接口也要另外构建。
    • json交互,谷歌爸爸鼓励使用json进行交互(一年多前的事,现在不清楚了),且安卓原生内置GJSON进行json解析与构建,所以可以在原生以及跨平台的构建有很好的平衡。

对比

既然选择了json交互的方式,而java官方据我所知是没有内置对json的支持,Spring在Controller的层面使用RestContrller注解实现对json的支持。
但是我个人强迫症很强,我对Contrller(或者说是Presenter)的定义是

  • 对用户访问的url作页面的映射
  • 对用户触发的事件进行数据的传递与返回
    正是这两点的定义,我需要在Service层组合统一格式的结果返回到上层,所以需要第三方json支持。
    可选择的JSON库有很多,GSON,FastJson,Jackson,根据对比,我选择为马老师充值一波。

需求拆分

我初步定义的需求主要有三个

  • Service传递统一处理结果到上层
  • 无论是单一数据实体或者List型数据处理的结果是一样的
  • 处理过程是独立的,不依赖于实体类的支持

格式设计

在网上看过很多后端返回数据的格式,很多都是返回一个处理的status以及具体的数据,而这个status是根据http状态码进行设定的,因为这次时间比较紧,所以我就采用了这个方案。

{
"status": "status",
"object": { }
}

代码设计

因为我希望Controller能直接拿到结果,所以构建结果的过程全放在Result类中。
而结果构建我主要分为两种:只有状态码(通知处理结果)以及具有返回结果(数据显示),而根据结果的个人也分为两种:单个数据以及List型数据。

实际代码

@Getter
@Slf4j
public class ResultSet { private JSONObject result; public ResultSet(){
result=new JSONObject();
} /**
* 初始化状态码
* @param status
*/
public void initStatus(String status){
result.put("status", status);
} /**
* 初始化状态码以及返回数据
* @param status
* @param obj
*/
public void initData(String status,Object obj){
initStatus(status);
if(obj instanceof List){
List list=(List)obj;
JSONArray array=new JSONArray();
for(Object object:list){
array.add(putObjectToJSON(object));
}
result.put("object",array);
}
else {
result.put("object",putObjectToJSON(obj));
}
} /**
* 将单个Object放入json文件中
* @param obj
* @return
*/
private JSONObject putObjectToJSON(Object obj){
JSONObject result=new JSONObject();
Field[] fields=obj.getClass().getDeclaredFields();
for(Field field:fields){
field.setAccessible(true);
String fieldName=field.getType().getSimpleName();
if(fieldName.equals("Department")||fieldName.equals("Job")){
JSONObject tempJson=new JSONObject();
try {
Object tempObject = field.get(obj);
Field[] tempFields=tempObject.getClass().getDeclaredFields();
for(Field tempField:tempFields){
tempField.setAccessible(true);
tempJson.put(tempField.getName(),tempField.get(tempObject));
tempField.setAccessible(false);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(fieldName.equals("Department")){
result.put("depart",tempJson);
}
else {
result.put("job",tempJson);
}
}
else {
try {
result.put(field.getName(),field.get(obj));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
field.setAccessible(false);
}
return result;
}
}

代码思路

  1. Service通过initStatus/initData传入数据/状态码进行对象的生成

  2. Controller通过result的getter方法获取处理结果

  3. 单个数据以及List数据的处理

    1. 单个对象直接通过putObjectToJSON进行处理
    2. List数据通过对象类型判断,向下转型,遍历元素形成JSONArray进行处理,对元素处理的方法也是采用putObjectToJSON
  4. 嵌套对象的处理

     public class Employee {
    
        private int id;
    
        private Department depart;
    
        private Job job;
    
        private String name;
    
     	..................
    }
    1. 通过反射获取对象的所有成员变量类型以及对应的值
    2. 遇到上述bean类含有嵌套自定义对象时,递归生成json文件加入到结果json中

结果演示

​ (左为单object型,右为List型)

不足之处

  1. 状态码的设置应该采用枚举类的赋值,能更好的约束返回的状态码
  2. 在对象转换方面,应该采用配置扫描的方式。在配置文件中写入bean的包所在,在嵌套对象转换时通过扫描配置文件的信息判断
  3. 在嵌套对象的转换方面,只是做了一层的嵌套转换,更多层的没有考虑到,之后会再重构的
  4. 对异常处理方面,只是简单的输出错误信息。应该对错误信息进行进一步的处理

后记

因为这次时间比较赶,从项目的立项到成品的建立花了5天时间,所以注意到很多细节,但是没有去处理。
有想过之后有时间的话将这个工具类的细节完善起来,形成jar包供自己或者供开源。

相关连接

这只是后台对结果的统一处理,我另外写了一篇文章:JSON工具类的构建(前端版本),配合使用效果更佳哦~

本文首发于cartoon的博客
转载请注明出处:https://cartoonyu.github.io/cartoon-blog/post/json/json工具类的构建后端版本/

JSON工具类的构建(后端版本)的更多相关文章

  1. JSON工具类的构建(前端版本)

    前言 在前后端交互的选择上,之前一直采用的是模板引擎(因为我只负责后端). 而这次的一个算是作业吧,前后端都是我,所以就研究了一下JSON交互在java web的应用(主要是前端). 优缺点 因为我是 ...

  2. Spring统一返回Json工具类,带分页信息

    前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...

  3. 用jackson封装的JSON工具类

    package hjp.smart4j.framework.util; import com.fasterxml.jackson.databind.ObjectMapper; import org.s ...

  4. Code片段 : .properties属性文件操作工具类 & JSON工具类

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...

  5. Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加

    package com.aherp.framework.util; import java.lang.reflect.Array;import java.lang.reflect.Method;imp ...

  6. Json工具类 - JsonUtils.java

    Json工具类,提供Json与对象之间的转换. 源码如下:(点击下载 - JsonUtils.java . gson-2.2.4.jar ) import java.lang.reflect.Type ...

  7. Java json工具类,jackson工具类,ObjectMapper工具类

    Java json工具类,jackson工具类,ObjectMapper工具类 >>>>>>>>>>>>>>> ...

  8. 强大的Java Json工具类

    转自: https://blog.csdn.net/u014676619/article/details/49624165 import java.io.BufferedReader; import ...

  9. HttpClientUntils工具类的使用测试及注意事项(包括我改进的工具类和Controller端的注意事项【附 Json 工具类】)

    HttpClient工具类(我改过): package com.taotao.httpclient; import java.io.IOException; import java.net.URI; ...

随机推荐

  1. 实验报告(六)&第八周学习总结

    班级 计科二班 学号 20188425 姓名 IM 完成时间2019/10/18 评分等级 实验六 Java异常 实验目的 理解异常的基本概念: 掌握异常处理方法及熟悉常见异常的捕获方法. 实验要求 ...

  2. javaIO流(二)--字节流与字符流

    一.流的基本概念 在java.io包中,File类是唯一一个与文件本身有关的程序处理类,但是File类只能操作文件本身,而不能操作文件内容,IO操作的核心意义在于输入和输出操作.而对于程序而言,输入和 ...

  3. Mybatis的分支选择和In循环

    Mybatis的分支选择: <choose> <when test="patientNo != null and patientNo != ''"> and ...

  4. ontouchstart ondragstart="return false" oncopy="return false;" oncut="return false onselectstart="return false" onpaste="return false"

    ontouchstart:  开始触屏事件. ondragstart="return false"  禁止拖拽 oncopy="return false" 禁止 ...

  5. Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/ssm]]

    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].Standard ...

  6. MariaDB学习笔记(二)

    七 索引索引:索引是创建在表上的,是对数据库表中的一列或多列的值进行排序的一种结构.索引可以提高查询的速度.索引有两种存储类型: B型树索引 哈希索引I nnoDB和MyISAM支持B型树索引,MEM ...

  7. Java8 LocalDate操作时间和日期的API

    时间项目中的涉及到的时间处理非常多,犹豫SimpleDateFormat的不安全性以及Calendar等类在计算时比较复杂, 往往我们都会使用工具类来封装较多的日期处理函数, 但是JDK8中新增了操作 ...

  8. sql datetime类型数据如果进行模糊查询

    select * from Table1 where CONVERT(nvarchar(50),CreateTime,120) like '%2019'

  9. 虚拟机复制的linux无法联网,解决Bringing up interface eth0: Device eth0 does not seem to be present, delaying initialization.

    一.问题描述 OS:centos 原因是拷贝虚拟机造成的. 使用vmworkstation打开虚拟机的时候,要选择copy而非move. 二.解决描述 网络上解决步骤各异,其实就一句话.只要保证vmw ...

  10. 安装双系统Windows+Centos安装完成之后提示双系统选项菜单!

    原因:在windows下安装centos系统完成之后重启无法显示windows系统菜单选项 1.安装Windows系统 2.安装Centos系统 3.在Centos系统中安装ntfs-3g yum i ...