java API接口动态返回字段

我们在写API接口时,有这样的需求,就是根据客户端选择的字段进行值返回;例如:我们调用淘宝的接口,由于接口字段太多,调用方可能指定需要返回的字段,接口返回相应的字段结果,今天自己要做一个简单实现:

  @Autowired
    OrderServiceImpl orderService;
    
    // 简单顶一个接口,参数中定义需要返回的字段
    @PostMapping("/test")
    private List<JSONObject> test(@RequestBody RequestParamVO paramVO){
        return orderService.getOrderList(paramVO);
    }

    @Data
    public class RequestParamVO {

        // 需要返回的字段,我们可能通过定义在枚举中,用户选择之后传回
        private List<String> fields;
        
    }

需要做的步骤:

  1. 首选要校验客户端传来的字段,是不是我们定义的字段,如果不是我们定义的字段,就移除这个字段,也方式SQL注入;我们将全部字段定义在OrderPO这个实体对象中;
public class OrderPO{
	private Long id;
    private String orderNo;
    private String name;
    private String phone;
    private String province;
    private String city;
    private String county;
    private String address;
    private BigDecimal orderPrice;
    private Integer status;
    }
     // 验证参数,出入的字段是对象中存在的字段,防止SQL注入
        List<String> fields = paramVO.getFields();
        // 我们把所有的字段定义在orderPO或者一个枚举中
        Field[] declaredFields = OrderPO.class.getDeclaredFields();
        Set<String> fieldSet = Arrays.stream(declaredFields).map(info -> info.getName()).collect(Collectors.toSet());
        // 字段校验,过滤不存在的字段
        Set<String> existFieldSet = fields.stream().filter(info -> fieldSet.contains(info)).collect(Collectors.toSet());
    ,,, 等等
  1. 第二步:根据用户自定的字段做mysql数据库查询,其中returnField就是根据用户定义字段转换而来
   // 这里通过SQL查询,需要返回的字段,转换为SQL查询字符串: order_no,name,phone,order_price
String returnField = existFieldSet.stream().map(info -> humpToLine(info)).collect(Collectors.joining(","));
        
  <select id="getOrderList" resultType="com.xxx.OrderPO">
       select
        ${returnField}
        from order
        limit 10
    </select>

  1. 第三步:就查询接口通过反射原因获取所需要的字段,封装到JSONObject对象中进行返回;
private static Pattern humpPattern = Pattern.compile("[A-Z]");
    // 将驼峰命名转为下划线名称
    public static String humpToLine(String str) {

        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
  @Autowired
    TestMapper testMapper;
    public List<JSONObject> getOrderList(RequestParamVO paramVO){
        // 验证参数,出入的字段是对象中存在的字段,防止SQL注入
        List<String> fields = paramVO.getFields();
        // 我们把所有的字段定义在orderPO或者一个枚举中
        Field[] declaredFields = OrderPO.class.getDeclaredFields();
        Set<String> fieldSet = Arrays.stream(declaredFields).map(info -> info.getName()).collect(Collectors.toSet());
        // 字段校验,过滤不存在的字段
        Set<String> existFieldSet = fields.stream().filter(info -> fieldSet.contains(info)).collect(Collectors.toSet());
        // 这里通过SQL查询,需要返回的字段,转换为SQL查询字符串: order_no,name,phone,order_price
        String returnField = existFieldSet.stream().map(info -> humpToLine(info)).collect(Collectors.joining(","));
        // 从mysql中查询数据
        List<OrderPO> orderList = testMapper.getOrderList(returnField);
        List<JSONObject> result = new ArrayList<>();
        if(!CollectionUtils.isEmpty(orderList)){
            for (OrderPO orderPO : orderList) {
                Field[] orderPOField = orderPO.getClass().getDeclaredFields();
                JSONObject object = new JSONObject();
                Arrays.stream(orderPOField).filter(info->existFieldSet.contains(info.getName()))
                        .forEach(info->{
                            try {
                                info.setAccessible(true);
                                object.put(info.getName(),info.get(orderPO));
                            } catch (IllegalAccessException e) {
                                log.error("字段转换异常");
                            }
                        });

                result.add(object);
            }
        }
        return result;

    }
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最新最全最好的java中文版API 1.6. 此 API 文档的组织方式 此 API(应用程序编程接口)文档包含对应于导航栏中的项目的页面,如下所述。 概述 概述 页面是此 API 文档的首页,提供了所有软件包的列表及其摘要。此页面也可能包含这些软件包的总体描述。 软件包 每个软件包都有一个页面,其中包含它的类和接口的列表及其摘要。此页面可以包含四个类别: 接口(斜体) 类 枚举 异常 错误 注释类型 类/接口 每个类、接口、嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分(类/接口描述、摘要表,以及详细的成员描述)组成: 类继承图 直接子类 所有已知子接口 所有已知实现类 类/接口声明 类/接口描述 嵌套类摘要 字段摘要 构造方法摘要 方法摘要 字段详细信息 构造方法详细信息 方法详细信息 每个摘要条目都包含该项目的详细描述的第一句。摘要条目按字母顺序排列,而详细描述则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。 注释类型 每个注释类型都有各自的页面,其中包含以下部分: 注释类型声明 注释类型描述 必需元素摘要 可选元素摘要 元素详细信息 枚举 每个枚举都有各自的页面,其中包含以下部分: 枚举声明 枚举描述 枚举常量摘要 枚举常量详细信息 使用 每个已文档化的软件包、类和接口都有各自的“使用”页面。此页面介绍了使用给定类或软件包的任何部分的软件包、类、方法、构造方法和字段。对于给定的类或接口 A,其“使用”页面包含 A 的子类、声明为 A 的字段返回 A 的方法,以及带有类型为 A 的参数的方法和构造方法。访问此页面的方法是:首先转至软件包、类或接口,然后单击导航栏中的“使用”链接。 树(类分层结构) 对于所有软件包,有一个 类分层结构 页面,以及每个软件包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从 java.lang.Object 开始,按继承结构对类进行排列。接口不从 java.lang.Object 继承。 查看“概述”页面时,单击“树”将显示所有软件包的分层结构。 查看特定软件包、类或接口页面时,单击“树”将仅显示该软件包的分层结构。 已过时的 API 已过时的 API 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API,所以建议不要使用已过时的 API。在将来的实施过程中,可能会删除已过时的 API。 索引 索引 包含按字母顺序排列的所有类、接口、构造方法、方法和字段的列表。
API(应用程序编程接口)文档包含对应于导航栏中的项目的页面,如下所述。 概述 概述 页面是此 API 文档的首页,提供了所有软件包的列表及其摘要。此页面也可能包含这些软件包的总体描述。 软件包 每个软件包都有一个页面,其中包含它的类和接口的列表及其摘要。此页面可以包含四个类别: •接口(斜体) •类 •枚举 •异常 •错误 •注释类型 类/接口 每个类、接口、嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分(类/接口描述、摘要表,以及详细的成员描述)组成: •类继承图 •直接子类 •所有已知子接口 •所有已知实现类 •类/接口声明 •类/接口描述 •嵌套类摘要 •字段摘要 •构造方法摘要 •方法摘要 •字段详细信息 •构造方法详细信息 •方法详细信息 每个摘要条目都包含该项目的详细描述的第一句。摘要条目按字母顺序排列,而详细描述则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。 注释类型 每个注释类型都有各自的页面,其中包含以下部分: •注释类型声明 •注释类型描述 •必需元素摘要 •可选元素摘要 •元素详细信息 枚举 每个枚举都有各自的页面,其中包含以下部分: •枚举声明 •枚举描述 •枚举常量摘要 •枚举常量详细信息 使用 每个已文档化的软件包、类和接口都有各自的“使用”页面。此页面介绍了使用给定类或软件包的任何部分的软件包、类、方法、构造方法和字段。对于给定的类或接口 A,其“使用”页面包含 A 的子类、声明为 A 的字段返回 A 的方法,以及带有类型为 A 的参数的方法和构造方法。访问此页面的方法是:首先转至软件包、类或接口,然后单击导航栏中的“使用”链接。 树(类分层结构) 对于所有软件包,有一个 类分层结构 页面,以及每个软件包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从 java.lang.Object 开始,按继承结构对类进行排列。接口不从 java.lang.Object 继承。•查看“概述”页面时,单击“树”将显示所有软件包的分层结构。 •查看特定软件包、类或接口页面时,单击“树”将仅显示该软件包的分层结构。 已过时的 API 已过时的 API 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API,所以建议不要使用已过时的 API。在将来的实施过程中,可能会删除已过时的 API。 索引 索引 包含按字母顺序排列的所有类、接口、构造方法、方法和字段的列表。 上一个/下一个 这些链接使您可以转至下一个或上一个类、接口、软件包或相关页面。 框架/无框架 这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。 序列化表格 每个可序列化或可外部化的类都有其序列化字段和方法的描述。此信息对重新实现者有用,而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接,但您可以通过下列方式获取此信息:转至任何序列化类,然后单击类描述的“另请参见”部分中的“序列化表格”。 常量字段值 常量字段值页面列出了静态最终字段及其值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值