Java解析实体类的属性和属性注释

前言

获取某个类的属性(字段)是我们经常都会碰到的,通常我们是通过反射来获取的。

但是有些特殊情况下,我们不仅要获取类的属性,还需要获取属性注释。这种情况下,我们只能通过注解去获取注释。可以自己定义一个专门用于设置注释的注解;如果项目中用了swagger的话,那就可以直接用swagger的@ApiModelProperty注解,这样就不用再单独自定义一个注解了。

假如不想通过反射和注解来获取也可以,那就可以通过以读取文件的形式读取这个java文件,解析注释和属性名。

实现

通过反射和注解获取

首先自定义一个注解(有用swagger就不用再定义了,直接用@ApiModelProperty就行)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 注释注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Comment {
    String value() default "";
}

使用:

@Data
public class SysUser {
	// 这两个注解任意选一个就行
    @Comment("名称")
    @ApiModelProperty(value = "名称")
    private String name;
}

反射获取:

public static void main(String[] args) {
	Map<String,String> map = new LinkedHashMap<>();
    StringBuilder sb = new StringBuilder(); // 转json格式
    sb.append("{\n");
    // 设置公共属性
    sb.append("\t\"").append("id").append("\"").append(":").append("\"").append("id").append("\"").append(",\n");
    sb.append("\t\"").append("creatorId").append("\"").append(":").append("\"").append("创建者").append("\"").append(",\n");
    sb.append("\t\"").append("createTime").append("\"").append(":").append("\"").append("创建时间").append("\"").append(",\n");
    sb.append("\t\"").append("updateId").append("\"").append(":").append("\"").append("更新者").append("\"").append(",\n");
    sb.append("\t\"").append("updateTime").append("\"").append(":").append("\"").append("更新时间").append("\"").append(",\n");
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        field.setAccessible(true);
        String fieldName = field.getName();
        //String fieldComment = field.getAnnotation(ApiModelProperty.class).value();
        String fieldComment = field.getAnnotation(Comment.class).value();
        sb.append("\t\"").append(fieldName).append("\"").append(":").append("\"").append(fieldComment).append("\"").append(",\n");
        map.put(fieldName, fieldComment);
    }
    sb.append("}");
    System.out.println(map);
    System.out.println(sb.toString());
}

输出结果:

在这里插入图片描述

读取文件的形式解析

要解析的类:

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.List;
import java.util.Map;

/**
 * 用户信息
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
public class SysUser extends BaseEntity {

    /**
     * 用户名称
     */
    @TableField("user_name")
    private String userName;

    /**
     * 用户姓名
     */
    @TableField("real_name")
    private String realName;

    /**
     * 所属部门
     */
    @TableField("dept_id")
    private String deptId;

    /**
     * 所属角色
     */
    @TableField("role_id")
    private String roleId;

    /**
     * 状态(1 启用 2 停用)
     */
    @TableField("state")
    private Integer state;

	/** token值 */
    @TableField(exist = false)
    private String token;
	// 部门名称
    @TableField(exist = false)
    private String deptName;
	/*
	 * 上级部门id
     */
    @TableField(exist = false)
    private String parentId;
	/* 上级部门名称 */
    @TableField(exist = false)
    private String parentName;
	/**
	 *角色代码
     */
    @TableField(exist = false)
    private String roleKey;
    /**
	*角色名称
     */
    @TableField(exist = false)
    private String roleName;
    /**角色信息*/
	@TableField(exist = false)
    private SysRole role;
	
	// 部门列表
    @TableField(exist = false)
    private List<SysDept> deptList;
    
	//部门列表
    @TableField(exist = false)
    private Map<String,Object> params;
}

上面的注释有单行注释、多行注释

开始解析:

/**
 * @param flag 是否需要拼接公共属性 true 需要 false 不用
 */
private static void entityToJSON(boolean flag){
    System.out.println("请输入实体类文件路径:");
    Scanner sc = new Scanner(System.in);
    String filePath = sc.next();
    File file = new File(filePath);
    if (!file.exists()){
        System.out.println("文件不存在!");
        return;
    }
    BufferedReader br = null;
    StringBuilder sb = new StringBuilder();
    sb.append("{\n");
    if (flag){
        // 设置公共属性
        sb.append("\t\"").append("id").append("\"").append(":").append("\"").append("id").append("\"").append(",\n");
        sb.append("\t\"").append("creatorId").append("\"").append(":").append("\"").append("创建者").append("\"").append(",\n");
        sb.append("\t\"").append("createTime").append("\"").append(":").append("\"").append("创建时间").append("\"").append(",\n");
        sb.append("\t\"").append("updateId").append("\"").append(":").append("\"").append("更新者").append("\"").append(",\n");
        sb.append("\t\"").append("updateTime").append("\"").append(":").append("\"").append("更新时间").append("\"").append(",\n");
    }
    try{
        br = new BufferedReader(new FileReader(file));
        String line = "";
        // 属性名、注释、上一个属性名
        String key = "",value = "",preKey = "",preValue = "";
        while ((line = br.readLine()) != null){
            String 内容 = line.trim(); // 每一行的内容,去掉空格
            //System.out.println(内容);
            if (内容.length() > 0){
                if ((内容.startsWith("*") && !内容.endsWith("*/")) || 内容.startsWith("//") || (内容.startsWith("/*") && 内容.endsWith("*/"))){
                    // 这里是解析属性注释
                    value = 内容.replace("/*","").replace("*/","")
                            .replace("*","").replace("//","").trim();
                }else if (内容.startsWith("private")){
                    // 这里是解析以 private 开头的属性名称
                    //key = 内容.replaceAll("private String |private Integer |private Long |private Double |;|private List<.*> ", "");
                    key = 内容.replaceAll("private .* |;", "").trim();
                }
                // 这里按照一行一行解析文件的话,注释是比属性先解析出来的,所以不能直接put
                // key不为空,并且不等于上一个属性名时才put
                if (StrUtil.isNotBlank(key) && !key.equals(preKey)){
                    // 当前属性和前一个注释才是相对应的
                    sb.append("\t\"").append(key).append("\"").append(":").append("\"").append(value).append("\"").append(",\n");
                }
                preKey = key;
            }
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    sb.append("}");
    System.out.println(sb.toString());
}

输出结果:

在这里插入图片描述

这样我们就可以将实体类转成JSON格式了。

最后

其实我是因为写接口文档需要用到json格式的数据,所以才想要获取属性注释。

一开始我是用实体类对应的数据库表来解析的,也就是解析一段建表SQL,不过因为有些实体类的属性在表里面是没有的,所以才有这个根据实体类来解析的实现。

如果有跟我一样需要用到 获取属性注释 的,可以参考下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/513344.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LC 111.二叉树的最小深度

111. 二叉树的最小深度 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a; 叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a;…

python读取excel,转换成json格式,for国际化前端菜单

# -*- coding: utf-8 -*-import pandas as pd import json# 读取Excel文件中的数据 excel_file rD:\解析excel\zy.xlsx df pd.read_excel(excel_file)# 生成中文JSON和英文JSON cn_data {} en_data {} pu_data {} special_data_cn {} special_data_en {} special_data_p…

肿瘤免疫反应瀑布图(源于The Miller Lab)

目录 数据格式 绘图 ①根据剂量 ②根据type ③根据治疗响应度 添加水平线 数据格式 肿瘤免疫响应数据 rm(list ls()) library(tidyverse) library(dplyr) library(knitr)#模拟数据 # We will randomly assign the two doses, 80 mg or 150 mg, to the 56 subjects Me…

使用 Docker 部署 Puter 云桌面系统

1&#xff09;Puter 介绍 :::info GitHub&#xff1a;https://github.com/HeyPuter/puter ::: Puter 是一个先进的开源桌面环境&#xff0c;运行在浏览器中&#xff0c;旨在具备丰富的功能、异常快速和高度可扩展性。它可以用于构建远程桌面环境&#xff0c;也可以作为云存储服…

【EI会议征稿】2024年智能计算、信号处理与计算机科学国际会议(ICSPCS 2024)

2024 International Conference on Intelligent Computing, Signal Processing and Computer Science (ICSPCS 2024) ●会议简介 2024年智能计算、信号处理与计算机科学国际会议&#xff08;ICSPCS 2024&#xff09;即将在青岛隆重开幕。本次会议将汇聚全球智能计算、信号处理…

【动态】江西省小型水库安全监测能力提升试点项目通过验收

近日&#xff0c;由北京国信华源科技有限公司和长江勘测规划设计研究有限责任公司联合承建的江西省小型水库安全监测能力提升试点项目圆满通过验收。 在项目业主单位的组织下&#xff0c;省项目部、特邀专家、县水利局二级项目部以及项目设计、监理、承建等单位的代表组成验收工…

C/C++后台研发需要点亮哪些技能树?

引言 在当今高速发展的信息技术领域&#xff0c;C/C作为底层性能卓越、灵活性强的语言&#xff0c;在后台开发中仍然占据着至关重要的地位&#xff0c;尤其是在高性能服务器、实时计算、嵌入式系统、游戏引擎及云计算基础设施等领域。成为一名优秀的C/C后台研发工程师&#xf…

200元预算可购买的阿里云服务器配置价格表

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

MySQL一条SQL语句的执行过程

MySQL一条SQL语句的执行过程可以大致分为以下几个步骤&#xff1a; mysq分层架构 为了理解这个问题&#xff0c;先从Mysql的架构说起&#xff0c;对于Mysql来说&#xff0c;大致可以分为3层架构。 网络连接层&#xff1a; 作为客户端和服务端的连接&#xff0c;连接器负责处…

共享单车安全保障利器,实名认证API名副其实!

&#x1f680; 引言 随着科技飞速跃进&#xff0c;共享单车已成为都市新宠儿, 为我们的生活带来方便的同时&#xff0c;一系列安全隐患也相伴而生: 公共资产需要大众守护&#xff0c;但有人却恶意损毁、任性挪用&#xff1b;让人揪心的现象愈发严重&#xff0c;是时候采取雷霆…

WHM面板安全设置与防护技巧

上周有一个Hostease的客户购买带WHM面板的服务器&#xff0c;咨询我们的在线客服&#xff0c;如何确保WHM面板的安全性&#xff0c;客户想要进行安全加固设置。可以尝试以下是一些WHM面板的安全设置和防护技巧&#xff1a; 定期更新软件和补丁&#xff1a;确保操作系统、WHM面…

实操:driver.js 实现产品导览、亮点、上下文帮助

官网 https://driverjs.com/ 依赖 <script src"https://cdn.jsdelivr.net/npm/driver.js1.0.1/dist/driver.js.iife.js"></script> <link rel"stylesheet" href"https://cdn.jsdelivr.net/npm/driver.js1.0.1/dist/driver.css"/…

算法基础 - 并查集

&#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 算法 - 并查集前言Quick FindQuick Union加权 Quick Union路径压缩的加权 Quick Union比较&#x1f604;总结 算法 - 并查集 前言 用于解决动态连通性问题&#xff0c;能动态连接两个点&#xff0c;并且判断两个点是否连…

一个问题串联 Java 的几个基础知识

前言 关于 “” 和 equals() 的区别这个问题&#xff0c;我之前一直搞的很乱&#xff0c;虽然面试的时候一直没有被问到&#xff0c;但是我感觉这种是属于最基础的知识&#xff0c;如果不懂好像不是很好。后来我发现通过这个问题&#xff0c;可以串联起很多的知识点&#xff0…

使用Bitmaps位图实现Redis签到

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Redis提供了Bitmaps这个“数据类型”可以实现对位的操作: (1) Bitmaps…

定时器与晶振时钟、中断系统、定时中断

定时器 简介&#xff1a; C51中的定时器和计数器是同一个硬件电路支持的&#xff0c;通过寄存器配置不同&#xff0c;就可以将他当做定时器 或者计数器使用。 确切的说&#xff0c;定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使用时&#xff0…

求批量修改图片扩展名有哪些方法?一键批量修改文件扩展名

批量修改图片的扩展名还可以帮助我们更好地管理和分类图片。在日常生活和工作中&#xff0c;我们可能会收集大量的图片&#xff0c;这些图片可能来自不同的来源&#xff0c;具有不同的格式和特点。通过批量修改扩展名&#xff0c;我们可以将这些图片进行统一的管理和分类&#…

【JAVASE】学习类与对象的创建和实例化

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 目标&#xff1a; 1. 掌握类的定义方式以及对象的实例化 2. …

视觉大模型--deter的深入理解

但对于transformer用于目标检测领域的开创性模型&#xff0c;该模型言简意赅&#xff0c;但是但从论文理解&#xff0c;有很多细节都不清楚&#xff0c;尤其是解码器的query和二分图匹配(Bipartite Matching)和匈牙利算法(Hungarian Algorithm)相关&#xff0c;本文将根据代码详…

Windows下Docker搭建Flink集群

编写docker-compose.yml 参照&#xff1a;https://github.com/docker-flink/examples/blob/master/docker-compose.yml version: "2.1" services:jobmanager:image: flink:1.14.4-scala_2.11expose:- "6123"ports:- "18081:8081"command: jobma…