Commit 9c1c26599357f3fc63160fb61ad8f759a078ac66
1 parent
53fbd985
解决各种 json 库的兼容性问题
Showing
12 changed files
with
66 additions
and
482 deletions
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java deleted
| 1 | -package com.ruoyi.web.controller.monitor; | ||
| 2 | - | ||
| 3 | -import org.springframework.security.access.prepost.PreAuthorize; | ||
| 4 | -import org.springframework.web.bind.annotation.GetMapping; | ||
| 5 | -import org.springframework.web.bind.annotation.RequestMapping; | ||
| 6 | -import org.springframework.web.bind.annotation.RestController; | ||
| 7 | -import com.ruoyi.common.core.domain.AjaxResult; | ||
| 8 | -import com.ruoyi.framework.web.domain.Server; | ||
| 9 | - | ||
| 10 | -/** | ||
| 11 | - * 服务器监控 | ||
| 12 | - * | ||
| 13 | - * @author ruoyi | ||
| 14 | - */ | ||
| 15 | -@RestController | ||
| 16 | -@RequestMapping("/monitor/server") | ||
| 17 | -public class ServerController { | ||
| 18 | - @PreAuthorize("@ss.hasPermi('monitor:server:list')") | ||
| 19 | - @GetMapping() | ||
| 20 | - public AjaxResult getInfo() throws Exception { | ||
| 21 | - Server server = new Server(); | ||
| 22 | - server.copyTo(); | ||
| 23 | - return AjaxResult.success(server); | ||
| 24 | - } | ||
| 25 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java deleted
| 1 | -package com.ruoyi.framework.web.domain; | ||
| 2 | - | ||
| 3 | -import java.net.UnknownHostException; | ||
| 4 | -import java.util.LinkedList; | ||
| 5 | -import java.util.List; | ||
| 6 | -import java.util.Properties; | ||
| 7 | - | ||
| 8 | -import com.ruoyi.common.utils.Arith; | ||
| 9 | -import com.ruoyi.common.utils.ip.IpUtils; | ||
| 10 | -import com.ruoyi.framework.web.domain.server.Cpu; | ||
| 11 | -import com.ruoyi.framework.web.domain.server.Jvm; | ||
| 12 | -import com.ruoyi.framework.web.domain.server.Mem; | ||
| 13 | -import com.ruoyi.framework.web.domain.server.Sys; | ||
| 14 | -import com.ruoyi.framework.web.domain.server.SysFile; | ||
| 15 | -import oshi.SystemInfo; | ||
| 16 | -import oshi.hardware.CentralProcessor; | ||
| 17 | -import oshi.hardware.CentralProcessor.TickType; | ||
| 18 | -import oshi.hardware.GlobalMemory; | ||
| 19 | -import oshi.hardware.HardwareAbstractionLayer; | ||
| 20 | -import oshi.software.os.FileSystem; | ||
| 21 | -import oshi.software.os.OSFileStore; | ||
| 22 | -import oshi.software.os.OperatingSystem; | ||
| 23 | -import oshi.util.Util; | ||
| 24 | - | ||
| 25 | -/** | ||
| 26 | - * 服务器相关信息 | ||
| 27 | - * | ||
| 28 | - * @author ruoyi | ||
| 29 | - */ | ||
| 30 | -public class Server { | ||
| 31 | - private static final int OSHI_WAIT_SECOND = 1000; | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * CPU相关信息 | ||
| 35 | - */ | ||
| 36 | - private Cpu cpu = new Cpu(); | ||
| 37 | - | ||
| 38 | - /** | ||
| 39 | - * 內存相关信息 | ||
| 40 | - */ | ||
| 41 | - private Mem mem = new Mem(); | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * JVM相关信息 | ||
| 45 | - */ | ||
| 46 | - private Jvm jvm = new Jvm(); | ||
| 47 | - | ||
| 48 | - /** | ||
| 49 | - * 服务器相关信息 | ||
| 50 | - */ | ||
| 51 | - private Sys sys = new Sys(); | ||
| 52 | - | ||
| 53 | - /** | ||
| 54 | - * 磁盘相关信息 | ||
| 55 | - */ | ||
| 56 | - private List<SysFile> sysFiles = new LinkedList<SysFile>(); | ||
| 57 | - | ||
| 58 | - public void copyTo() throws Exception { | ||
| 59 | - SystemInfo si = new SystemInfo(); | ||
| 60 | - HardwareAbstractionLayer hal = si.getHardware(); | ||
| 61 | - | ||
| 62 | - setCpuInfo(hal.getProcessor()); | ||
| 63 | - | ||
| 64 | - setMemInfo(hal.getMemory()); | ||
| 65 | - | ||
| 66 | - setSysInfo(); | ||
| 67 | - | ||
| 68 | - setJvmInfo(); | ||
| 69 | - | ||
| 70 | - setSysFiles(si.getOperatingSystem()); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - /** | ||
| 74 | - * 设置CPU信息 | ||
| 75 | - */ | ||
| 76 | - private void setCpuInfo(CentralProcessor processor) { | ||
| 77 | - // CPU信息 | ||
| 78 | - long[] prevTicks = processor.getSystemCpuLoadTicks(); | ||
| 79 | - Util.sleep(OSHI_WAIT_SECOND); | ||
| 80 | - long[] ticks = processor.getSystemCpuLoadTicks(); | ||
| 81 | - long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; | ||
| 82 | - long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; | ||
| 83 | - long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; | ||
| 84 | - long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; | ||
| 85 | - long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; | ||
| 86 | - long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; | ||
| 87 | - long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; | ||
| 88 | - long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; | ||
| 89 | - long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; | ||
| 90 | - cpu.setCpuNum(processor.getLogicalProcessorCount()); | ||
| 91 | - cpu.setTotal(totalCpu); | ||
| 92 | - cpu.setSys(cSys); | ||
| 93 | - cpu.setUsed(user); | ||
| 94 | - cpu.setWait(iowait); | ||
| 95 | - cpu.setFree(idle); | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - /** | ||
| 99 | - * 设置内存信息 | ||
| 100 | - */ | ||
| 101 | - private void setMemInfo(GlobalMemory memory) { | ||
| 102 | - mem.setTotal(memory.getTotal()); | ||
| 103 | - mem.setUsed(memory.getTotal() - memory.getAvailable()); | ||
| 104 | - mem.setFree(memory.getAvailable()); | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - /** | ||
| 108 | - * 设置服务器信息 | ||
| 109 | - */ | ||
| 110 | - private void setSysInfo() { | ||
| 111 | - Properties props = System.getProperties(); | ||
| 112 | - sys.setComputerName(IpUtils.getHostName()); | ||
| 113 | - sys.setComputerIp(IpUtils.getHostIp()); | ||
| 114 | - sys.setOsName(props.getProperty("os.name")); | ||
| 115 | - sys.setOsArch(props.getProperty("os.arch")); | ||
| 116 | - sys.setUserDir(props.getProperty("user.dir")); | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - /** | ||
| 120 | - * 设置Java虚拟机 | ||
| 121 | - */ | ||
| 122 | - private void setJvmInfo() throws UnknownHostException { | ||
| 123 | - Properties props = System.getProperties(); | ||
| 124 | - jvm.setTotal(Runtime.getRuntime().totalMemory()); | ||
| 125 | - jvm.setMax(Runtime.getRuntime().maxMemory()); | ||
| 126 | - jvm.setFree(Runtime.getRuntime().freeMemory()); | ||
| 127 | - jvm.setVersion(props.getProperty("java.version")); | ||
| 128 | - jvm.setHome(props.getProperty("java.home")); | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - /** | ||
| 132 | - * 设置磁盘信息 | ||
| 133 | - */ | ||
| 134 | - private void setSysFiles(OperatingSystem os) { | ||
| 135 | - FileSystem fileSystem = os.getFileSystem(); | ||
| 136 | - List<OSFileStore> fsArray = fileSystem.getFileStores(); | ||
| 137 | - for (OSFileStore fs : fsArray) { | ||
| 138 | - long free = fs.getUsableSpace(); | ||
| 139 | - long total = fs.getTotalSpace(); | ||
| 140 | - long used = total - free; | ||
| 141 | - SysFile sysFile = new SysFile(); | ||
| 142 | - sysFile.setDirName(fs.getMount()); | ||
| 143 | - sysFile.setSysTypeName(fs.getType()); | ||
| 144 | - sysFile.setTypeName(fs.getName()); | ||
| 145 | - sysFile.setTotal(convertFileSize(total)); | ||
| 146 | - sysFile.setFree(convertFileSize(free)); | ||
| 147 | - sysFile.setUsed(convertFileSize(used)); | ||
| 148 | - sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100)); | ||
| 149 | - sysFiles.add(sysFile); | ||
| 150 | - } | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - /** | ||
| 154 | - * 字节转换 | ||
| 155 | - * | ||
| 156 | - * @param size 字节大小 | ||
| 157 | - * @return 转换后值 | ||
| 158 | - */ | ||
| 159 | - public String convertFileSize(long size) { | ||
| 160 | - long kb = 1024; | ||
| 161 | - long mb = kb * 1024; | ||
| 162 | - long gb = mb * 1024; | ||
| 163 | - if (size >= gb) { | ||
| 164 | - return String.format("%.1f GB", (float) size / gb); | ||
| 165 | - } else if (size >= mb) { | ||
| 166 | - float f = (float) size / mb; | ||
| 167 | - return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); | ||
| 168 | - } else if (size >= kb) { | ||
| 169 | - float f = (float) size / kb; | ||
| 170 | - return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); | ||
| 171 | - } else { | ||
| 172 | - return String.format("%d B", size); | ||
| 173 | - } | ||
| 174 | - } | ||
| 175 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java deleted
| 1 | -package com.ruoyi.framework.web.domain.server; | ||
| 2 | - | ||
| 3 | -import com.ruoyi.common.utils.Arith; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * CPU相关信息 | ||
| 7 | - * | ||
| 8 | - * @author ruoyi | ||
| 9 | - */ | ||
| 10 | -public class Cpu { | ||
| 11 | - /** | ||
| 12 | - * 核心数 | ||
| 13 | - */ | ||
| 14 | - private int cpuNum; | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * CPU总的使用率 | ||
| 18 | - */ | ||
| 19 | - private double total; | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * CPU系统使用率 | ||
| 23 | - */ | ||
| 24 | - private double sys; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * CPU用户使用率 | ||
| 28 | - */ | ||
| 29 | - private double used; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * CPU当前等待率 | ||
| 33 | - */ | ||
| 34 | - private double wait; | ||
| 35 | - | ||
| 36 | - /** | ||
| 37 | - * CPU当前空闲率 | ||
| 38 | - */ | ||
| 39 | - private double free; | ||
| 40 | - | ||
| 41 | - public double getTotal() { | ||
| 42 | - return Arith.round(Arith.mul(total, 100), 2); | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - public double getSys() { | ||
| 46 | - return Arith.round(Arith.mul(sys / total, 100), 2); | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - public double getUsed() { | ||
| 50 | - return Arith.round(Arith.mul(used / total, 100), 2); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - public double getWait() { | ||
| 54 | - return Arith.round(Arith.mul(wait / total, 100), 2); | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - public double getFree() { | ||
| 58 | - return Arith.round(Arith.mul(free / total, 100), 2); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java deleted
| 1 | -package com.ruoyi.framework.web.domain.server; | ||
| 2 | - | ||
| 3 | -import java.lang.management.ManagementFactory; | ||
| 4 | - | ||
| 5 | -import com.ruoyi.common.utils.Arith; | ||
| 6 | -import com.ruoyi.common.utils.DateUtils; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * JVM相关信息 | ||
| 10 | - * | ||
| 11 | - * @author ruoyi | ||
| 12 | - */ | ||
| 13 | -public class Jvm { | ||
| 14 | - /** | ||
| 15 | - * 当前JVM占用的内存总数(M) | ||
| 16 | - */ | ||
| 17 | - private double total; | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * JVM最大可用内存总数(M) | ||
| 21 | - */ | ||
| 22 | - private double max; | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * JVM空闲内存(M) | ||
| 26 | - */ | ||
| 27 | - private double free; | ||
| 28 | - | ||
| 29 | - /** | ||
| 30 | - * JDK版本 | ||
| 31 | - */ | ||
| 32 | - private String version; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * JDK路径 | ||
| 36 | - */ | ||
| 37 | - private String home; | ||
| 38 | - | ||
| 39 | - public double getTotal() { | ||
| 40 | - return Arith.div(total, (1024 * 1024), 2); | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - public double getMax() { | ||
| 44 | - return Arith.div(max, (1024 * 1024), 2); | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - public double getFree() { | ||
| 48 | - return Arith.div(free, (1024 * 1024), 2); | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - public void setFree(double free) { | ||
| 52 | - this.free = free; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - public double getUsed() { | ||
| 56 | - return Arith.div(total - free, (1024 * 1024), 2); | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - public double getUsage() { | ||
| 60 | - return Arith.mul(Arith.div(total - free, total, 4), 100); | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - /** | ||
| 64 | - * 获取JDK名称 | ||
| 65 | - */ | ||
| 66 | - public String getName() { | ||
| 67 | - return ManagementFactory.getRuntimeMXBean().getVmName(); | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - /** | ||
| 71 | - * JDK启动时间 | ||
| 72 | - */ | ||
| 73 | - public String getStartTime() { | ||
| 74 | - return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - /** | ||
| 78 | - * JDK运行时间 | ||
| 79 | - */ | ||
| 80 | - public String getRunTime() { | ||
| 81 | - return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate()); | ||
| 82 | - } | ||
| 83 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java deleted
| 1 | -package com.ruoyi.framework.web.domain.server; | ||
| 2 | - | ||
| 3 | -import com.ruoyi.common.utils.Arith; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * 內存相关信息 | ||
| 7 | - * | ||
| 8 | - * @author ruoyi | ||
| 9 | - */ | ||
| 10 | -public class Mem { | ||
| 11 | - /** | ||
| 12 | - * 内存总量 | ||
| 13 | - */ | ||
| 14 | - private double total; | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 已用内存 | ||
| 18 | - */ | ||
| 19 | - private double used; | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * 剩余内存 | ||
| 23 | - */ | ||
| 24 | - private double free; | ||
| 25 | - | ||
| 26 | - public double getTotal() { | ||
| 27 | - return Arith.div(total, (1024 * 1024 * 1024), 2); | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - public double getUsed() { | ||
| 31 | - return Arith.div(used, (1024 * 1024 * 1024), 2); | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - public double getFree() { | ||
| 35 | - return Arith.div(free, (1024 * 1024 * 1024), 2); | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - public double getUsage() { | ||
| 39 | - return Arith.mul(Arith.div(used, total, 4), 100); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java deleted
| 1 | -package com.ruoyi.framework.web.domain.server; | ||
| 2 | - | ||
| 3 | -/** | ||
| 4 | - * 系统相关信息 | ||
| 5 | - * | ||
| 6 | - * @author ruoyi | ||
| 7 | - */ | ||
| 8 | -public class Sys { | ||
| 9 | - /** | ||
| 10 | - * 服务器名称 | ||
| 11 | - */ | ||
| 12 | - private String computerName; | ||
| 13 | - | ||
| 14 | - /** | ||
| 15 | - * 服务器Ip | ||
| 16 | - */ | ||
| 17 | - private String computerIp; | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * 项目路径 | ||
| 21 | - */ | ||
| 22 | - private String userDir; | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 操作系统 | ||
| 26 | - */ | ||
| 27 | - private String osName; | ||
| 28 | - | ||
| 29 | - /** | ||
| 30 | - * 系统架构 | ||
| 31 | - */ | ||
| 32 | - private String osArch; | ||
| 33 | - | ||
| 34 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java deleted
| 1 | -package com.ruoyi.framework.web.domain.server; | ||
| 2 | - | ||
| 3 | -/** | ||
| 4 | - * 系统文件相关信息 | ||
| 5 | - * | ||
| 6 | - * @author ruoyi | ||
| 7 | - */ | ||
| 8 | -public class SysFile { | ||
| 9 | - /** | ||
| 10 | - * 盘符路径 | ||
| 11 | - */ | ||
| 12 | - private String dirName; | ||
| 13 | - | ||
| 14 | - /** | ||
| 15 | - * 盘符类型 | ||
| 16 | - */ | ||
| 17 | - private String sysTypeName; | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * 文件类型 | ||
| 21 | - */ | ||
| 22 | - private String typeName; | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 总大小 | ||
| 26 | - */ | ||
| 27 | - private String total; | ||
| 28 | - | ||
| 29 | - /** | ||
| 30 | - * 剩余大小 | ||
| 31 | - */ | ||
| 32 | - private String free; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * 已经使用量 | ||
| 36 | - */ | ||
| 37 | - private String used; | ||
| 38 | - | ||
| 39 | - /** | ||
| 40 | - * 资源的使用率 | ||
| 41 | - */ | ||
| 42 | - private double usage; | ||
| 43 | - | ||
| 44 | -} |
src/main/java/cn/iocoder/dashboard/common/pojo/CommonResult.java
| @@ -5,6 +5,7 @@ import cn.iocoder.dashboard.common.exception.GlobalException; | @@ -5,6 +5,7 @@ import cn.iocoder.dashboard.common.exception.GlobalException; | ||
| 5 | import cn.iocoder.dashboard.common.exception.ServiceException; | 5 | import cn.iocoder.dashboard.common.exception.ServiceException; |
| 6 | import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; | 6 | import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; |
| 7 | import com.alibaba.fastjson.annotation.JSONField; | 7 | import com.alibaba.fastjson.annotation.JSONField; |
| 8 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| 8 | import lombok.Data; | 9 | import lombok.Data; |
| 9 | import org.springframework.util.Assert; | 10 | import org.springframework.util.Assert; |
| 10 | 11 | ||
| @@ -68,12 +69,14 @@ public final class CommonResult<T> implements Serializable { | @@ -68,12 +69,14 @@ public final class CommonResult<T> implements Serializable { | ||
| 68 | return result; | 69 | return result; |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | - @JSONField(serialize = false) // 避免序列化 | 72 | + @JSONField(serialize = false) // 避免 fastjson 序列化 |
| 73 | + @JsonIgnore // 避免 jackson 序列化 | ||
| 72 | public boolean isSuccess() { | 74 | public boolean isSuccess() { |
| 73 | return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code); | 75 | return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code); |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | - @JSONField(serialize = false) // 避免序列化 | 78 | + @JSONField(serialize = false) // 避免 fastjson 序列化 |
| 79 | + @JsonIgnore // 避免 jackson 序列化 | ||
| 77 | public boolean isError() { | 80 | public boolean isError() { |
| 78 | return !isSuccess(); | 81 | return !isSuccess(); |
| 79 | } | 82 | } |
src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
| 1 | package cn.iocoder.dashboard.framework.web.config; | 1 | package cn.iocoder.dashboard.framework.web.config; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.util.servlet.ServletUtils; | ||
| 4 | +import com.alibaba.fastjson.serializer.SerializerFeature; | ||
| 5 | +import com.alibaba.fastjson.support.config.FastJsonConfig; | ||
| 6 | +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; | ||
| 3 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 4 | import org.springframework.context.annotation.Bean; | 8 | import org.springframework.context.annotation.Bean; |
| 5 | import org.springframework.context.annotation.Configuration; | 9 | import org.springframework.context.annotation.Configuration; |
| 6 | import org.springframework.core.annotation.Order; | 10 | import org.springframework.core.annotation.Order; |
| 11 | +import org.springframework.http.MediaType; | ||
| 12 | +import org.springframework.http.converter.HttpMessageConverter; | ||
| 7 | import org.springframework.web.bind.annotation.RestController; | 13 | import org.springframework.web.bind.annotation.RestController; |
| 8 | import org.springframework.web.cors.CorsConfiguration; | 14 | import org.springframework.web.cors.CorsConfiguration; |
| 9 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | 15 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| @@ -12,6 +18,10 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; | @@ -12,6 +18,10 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; | ||
| 12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | 18 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| 13 | 19 | ||
| 14 | import javax.annotation.Resource; | 20 | import javax.annotation.Resource; |
| 21 | +import javax.servlet.http.HttpServletRequest; | ||
| 22 | +import java.nio.charset.Charset; | ||
| 23 | +import java.util.Collections; | ||
| 24 | +import java.util.List; | ||
| 15 | 25 | ||
| 16 | /** | 26 | /** |
| 17 | * Web 配置类 | 27 | * Web 配置类 |
| @@ -27,26 +37,48 @@ public class WebConfiguration implements WebMvcConfigurer { | @@ -27,26 +37,48 @@ public class WebConfiguration implements WebMvcConfigurer { | ||
| 27 | public void configurePathMatch(PathMatchConfigurer configurer) { | 37 | public void configurePathMatch(PathMatchConfigurer configurer) { |
| 28 | configurer.addPathPrefix(webProperties.getApiPrefix(), clazz -> | 38 | configurer.addPathPrefix(webProperties.getApiPrefix(), clazz -> |
| 29 | clazz.isAnnotationPresent(RestController.class) | 39 | clazz.isAnnotationPresent(RestController.class) |
| 30 | - && clazz.getPackage().getName().contains("cn.iocoder.dashboard")); | 40 | + && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage())); |
| 31 | } | 41 | } |
| 32 | 42 | ||
| 33 | // ========== MessageConverter 相关 ========== | 43 | // ========== MessageConverter 相关 ========== |
| 34 | 44 | ||
| 35 | -// @Override | ||
| 36 | -// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | ||
| 37 | -// // 创建 FastJsonHttpMessageConverter 对象 | ||
| 38 | -// FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); | ||
| 39 | -// // 自定义 FastJson 配置 | ||
| 40 | -// FastJsonConfig fastJsonConfig = new FastJsonConfig(); | ||
| 41 | -// fastJsonConfig.setCharset(Charset.defaultCharset()); // 设置字符集 | ||
| 42 | -// fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, // 剔除循环引用 | ||
| 43 | -// SerializerFeature.WriteNonStringKeyAsString); // 解决 Integer 作为 Key 时,转换为 String 类型,避免浏览器报错 | ||
| 44 | -// fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); | ||
| 45 | -// // 设置支持的 MediaType | ||
| 46 | -// fastJsonHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); | ||
| 47 | -// // 添加到 converters 中 | ||
| 48 | -// converters.add(0, fastJsonHttpMessageConverter); // 注意,添加到最开头,放在 MappingJackson2XmlHttpMessageConverter 前面 | ||
| 49 | -// } | 45 | + @Override |
| 46 | + public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | ||
| 47 | + // 创建 FastJsonHttpMessageConverter 对象 | ||
| 48 | + // 重写 canRead 和 canWrite 方法,判断只处理自己写的 API 为前缀的 URL。原因是,FastJSON 和一些三方框架集成存在问题,例如说: | ||
| 49 | + // 1. 与 Spring Boot Admin 时,由于 Registration 基于 Builder 构造对象,导致它无法反序列化 | ||
| 50 | + // 2. 与 Spring Boot Actuator 时,貌似也存在问题,具体还没去排查。 | ||
| 51 | + // 但是,为什么不替换回 Jackson 呢? | ||
| 52 | + // 原因是,一些 Number 数值比较小时,反序列化回来是 Integer 类型,实际是 Long 类型。此时,在序列化时,会报 Integer 无法转换成 Long 的异常 | ||
| 53 | + FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter() { | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + protected boolean canRead(MediaType mediaType) { | ||
| 57 | + return isApiPrefix() && super.canRead(mediaType); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + protected boolean canWrite(MediaType mediaType) { | ||
| 62 | + return isApiPrefix() && super.canWrite(mediaType); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + private boolean isApiPrefix() { | ||
| 66 | + HttpServletRequest request = ServletUtils.getRequest(); | ||
| 67 | + return request != null && request.getRequestURI().startsWith(webProperties.getApiPrefix()); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + }; | ||
| 71 | + // 自定义 FastJson 配置 | ||
| 72 | + FastJsonConfig fastJsonConfig = new FastJsonConfig(); | ||
| 73 | + fastJsonConfig.setCharset(Charset.defaultCharset()); // 设置字符集 | ||
| 74 | + fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, // 剔除循环引用 | ||
| 75 | + SerializerFeature.WriteNonStringKeyAsString); // 解决 Integer 作为 Key 时,转换为 String 类型,避免浏览器报错 | ||
| 76 | + fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); | ||
| 77 | + // 设置支持的 MediaType | ||
| 78 | + fastJsonHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); | ||
| 79 | + // 添加到 converters 中 | ||
| 80 | + converters.add(0, fastJsonHttpMessageConverter); // 注意,添加到最开头,放在 MappingJackson2XmlHttpMessageConverter 前面 | ||
| 81 | + } | ||
| 50 | 82 | ||
| 51 | // ========== Filter 相关 ========== | 83 | // ========== Filter 相关 ========== |
| 52 | 84 |
src/main/java/cn/iocoder/dashboard/framework/web/config/WebProperties.java
| @@ -24,4 +24,14 @@ public class WebProperties { | @@ -24,4 +24,14 @@ public class WebProperties { | ||
| 24 | @NotNull(message = "API 前缀不能为空") | 24 | @NotNull(message = "API 前缀不能为空") |
| 25 | private String apiPrefix; | 25 | private String apiPrefix; |
| 26 | 26 | ||
| 27 | + /** | ||
| 28 | + * Controller 所在包 | ||
| 29 | + * | ||
| 30 | + * 主要目的是,给该 Controller 设置指定的 {@link #apiPrefix} | ||
| 31 | + * | ||
| 32 | + * 因为我们有多个 modules 包里会包含 Controller,所以只需要写到 cn.iocoder.dashboard 这样的层级 | ||
| 33 | + */ | ||
| 34 | + @NotNull(message = "Controller 所在包不能为空") | ||
| 35 | + private String controllerPackage; | ||
| 36 | + | ||
| 27 | } | 37 | } |
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserPageItemRespVO.java
| 1 | package cn.iocoder.dashboard.modules.system.controller.user.vo.user; | 1 | package cn.iocoder.dashboard.modules.system.controller.user.vo.user; |
| 2 | 2 | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| 3 | import io.swagger.annotations.ApiModel; | 4 | import io.swagger.annotations.ApiModel; |
| 4 | import io.swagger.annotations.ApiModelProperty; | 5 | import io.swagger.annotations.ApiModelProperty; |
| 5 | import lombok.AllArgsConstructor; | 6 | import lombok.AllArgsConstructor; |
| @@ -17,6 +18,7 @@ public class SysUserPageItemRespVO extends SysUserRespVO { | @@ -17,6 +18,7 @@ public class SysUserPageItemRespVO extends SysUserRespVO { | ||
| 17 | /** | 18 | /** |
| 18 | * 所在部门 | 19 | * 所在部门 |
| 19 | */ | 20 | */ |
| 21 | + @JsonIgnore | ||
| 20 | private Dept dept; | 22 | private Dept dept; |
| 21 | 23 | ||
| 22 | @ApiModel("部门") | 24 | @ApiModel("部门") |
src/main/resources/application.yaml
| @@ -36,6 +36,7 @@ spring: | @@ -36,6 +36,7 @@ spring: | ||
| 36 | yudao: | 36 | yudao: |
| 37 | web: | 37 | web: |
| 38 | api-prefix: /api | 38 | api-prefix: /api |
| 39 | + controller-package: cn.iocoder.dashboard | ||
| 39 | security: | 40 | security: |
| 40 | token-header: Authorization | 41 | token-header: Authorization |
| 41 | token-secret: abcdefghijklmnopqrstuvwxyz | 42 | token-secret: abcdefghijklmnopqrstuvwxyz |