移除系统监控模块 SysUserController部分功能拆分至AccountController socket参数修改:session_id->token 其他代码修改master
parent
14404fa6a4
commit
9609078727
@ -0,0 +1,19 @@ |
||||
package com.toesbieya.my.config; |
||||
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature; |
||||
import com.alibaba.fastjson.support.config.FastJsonConfig; |
||||
|
||||
public class FastJsonConfigFactory { |
||||
public static FastJsonConfig defaultConfig() { |
||||
FastJsonConfig config = new FastJsonConfig(); |
||||
|
||||
config.setSerializerFeatures( |
||||
SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段
|
||||
SerializerFeature.WriteDateUseDateFormat, |
||||
SerializerFeature.WriteNullListAsEmpty, |
||||
SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
|
||||
); |
||||
|
||||
return config; |
||||
} |
||||
} |
||||
@ -1,70 +0,0 @@ |
||||
package com.toesbieya.my.config; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import com.toesbieya.my.module.SocketModule; |
||||
import com.toesbieya.my.utils.Util; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.redis.serializer.RedisSerializer; |
||||
import org.springframework.data.redis.serializer.SerializationException; |
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; |
||||
|
||||
import javax.servlet.http.HttpSessionEvent; |
||||
import javax.servlet.http.HttpSessionListener; |
||||
import java.nio.charset.Charset; |
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
@Configuration |
||||
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 28800) |
||||
public class HttpSessionConfig { |
||||
@Bean |
||||
public HttpSessionListener httpSessionEventPublisher() { |
||||
return new HttpSessionListener() { |
||||
@Override |
||||
public void sessionCreated(HttpSessionEvent se) { |
||||
} |
||||
|
||||
@Override |
||||
public void sessionDestroyed(HttpSessionEvent se) { |
||||
SysUser user = Util.getUser(se.getSession()); |
||||
if (user != null) { |
||||
SocketModule.logout(user.getId(), "登陆状态过期,请重新登陆"); |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Bean("springSessionDefaultRedisSerializer") |
||||
public RedisSerializer<Object> defaultRedisSerializer() { |
||||
return new JsonRedisSerializer<>(Object.class); |
||||
} |
||||
|
||||
private class JsonRedisSerializer<T> implements RedisSerializer<T> { |
||||
|
||||
private final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; |
||||
|
||||
private final Class<T> clazz; |
||||
|
||||
public JsonRedisSerializer(Class<T> clazz) { |
||||
this.clazz = clazz; |
||||
} |
||||
|
||||
@Override |
||||
public byte[] serialize(T t) throws SerializationException { |
||||
if (t == null) { |
||||
return new byte[0]; |
||||
} |
||||
return JSON.toJSONString(t).getBytes(DEFAULT_CHARSET); |
||||
} |
||||
|
||||
@Override |
||||
public T deserialize(byte[] bytes) throws SerializationException { |
||||
if (bytes == null || bytes.length <= 0) { |
||||
return null; |
||||
} |
||||
String str = new String(bytes, DEFAULT_CHARSET); |
||||
return JSON.parseObject(str, clazz); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,22 @@ |
||||
package com.toesbieya.my.config; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
@ConfigurationProperties("qiniu") |
||||
@Data |
||||
public class QiniuConfig { |
||||
private String accessKey; |
||||
|
||||
private String secretKey; |
||||
|
||||
private String bucket; |
||||
|
||||
//临时上传凭证的有效期,单位秒
|
||||
private Integer tokenExpire = 3600; |
||||
|
||||
//临时上传凭证的redis键名
|
||||
private String redisCacheKey = "qiniu-token"; |
||||
} |
||||
@ -1,27 +1,15 @@ |
||||
package com.toesbieya.my.config; |
||||
|
||||
import com.corundumstudio.socketio.SocketIOServer; |
||||
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; |
||||
import com.toesbieya.my.constant.SocketConstant; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Configuration |
||||
@Component |
||||
@ConfigurationProperties("socket") |
||||
@Data |
||||
public class SocketConfig { |
||||
|
||||
@Bean |
||||
public SocketIOServer socketIOServer() { |
||||
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration(); |
||||
config.setHostname(SocketConstant.HOSTNAME); |
||||
config.setPort(SocketConstant.PORT); |
||||
config.setMaxFramePayloadLength(SocketConstant.MAX_FRAME_PAYLOAD); |
||||
config.setMaxHttpContentLength(SocketConstant.MAX_HTTP_CONTENT); |
||||
config.setAddVersionHeader(false); |
||||
return new SocketIOServer(config); |
||||
} |
||||
|
||||
@Bean |
||||
public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { |
||||
return new SpringAnnotationScanner(socketServer); |
||||
} |
||||
private String hostname = "localhost"; |
||||
private Integer port = 12580; |
||||
private Integer maxFramePayloadLength = 1024 * 1024; |
||||
private Integer maxHttpContentLength = 1024 * 1024; |
||||
} |
||||
|
||||
@ -0,0 +1,37 @@ |
||||
package com.toesbieya.my.config; |
||||
|
||||
import com.corundumstudio.socketio.SocketIOServer; |
||||
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.DependsOn; |
||||
|
||||
@Configuration |
||||
@DependsOn("redisUtil") |
||||
public class SocketServerConfig { |
||||
private SocketConfig socketConfig; |
||||
|
||||
@Bean |
||||
public SocketIOServer socketIOServer() { |
||||
com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration(); |
||||
|
||||
config.setHostname(socketConfig.getHostname()); |
||||
config.setPort(socketConfig.getPort()); |
||||
config.setMaxFramePayloadLength(socketConfig.getMaxFramePayloadLength()); |
||||
config.setMaxHttpContentLength(socketConfig.getMaxHttpContentLength()); |
||||
|
||||
config.setAddVersionHeader(false); |
||||
return new SocketIOServer(config); |
||||
} |
||||
|
||||
@Bean |
||||
public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { |
||||
return new SpringAnnotationScanner(socketServer); |
||||
} |
||||
|
||||
@Autowired |
||||
public void setSocketConfig(SocketConfig socketConfig) { |
||||
this.socketConfig = socketConfig; |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@ |
||||
package com.toesbieya.my.constant; |
||||
|
||||
public class DocumentConstant { |
||||
public static final String UPDATE_DOCUMENTS_LOCK_KEY = "UPDATE_DOCUMENTS"; |
||||
public static final String[] DOCUMENT_TYPE = {"CGDD", "CGRK", "CGTH", "XSDD", "XSCK", "XSTH"}; |
||||
public static final String DOCUMENT_TYPE_REDIS_KEY = "documentsID"; |
||||
} |
||||
@ -1,8 +1,6 @@ |
||||
package com.toesbieya.my.constant; |
||||
|
||||
public class SessionConstant { |
||||
public static String REDIS_NAMESPACE = "spring:session:sessions:"; |
||||
public static String USER_KEY = "user"; |
||||
public static String REDIS_NAMESPACE = "sessions:"; |
||||
public static String TOKEN_KEY = "X-Token"; |
||||
public static Integer PREDICT_MAX_USER = 128; |
||||
} |
||||
|
||||
@ -1,12 +1,14 @@ |
||||
package com.toesbieya.my.constant; |
||||
|
||||
import com.toesbieya.my.utils.YmlUtil; |
||||
|
||||
public class SocketConstant { |
||||
public static final String HOSTNAME = (String) YmlUtil.get("socket.hostname"); |
||||
public static final int PORT = (int) YmlUtil.get("socket.port"); |
||||
public static final int MAX_FRAME_PAYLOAD = (int) YmlUtil.get("socket.max-frame-payload"); |
||||
public static final int MAX_HTTP_CONTENT = (int) YmlUtil.get("socket.max-http-content"); |
||||
public static final String EVENT_LOGOUT = (String) YmlUtil.get("socket.event.logout"); |
||||
public static final String EVENT_NEW_MESSAGE = (String) YmlUtil.get("socket.event.new-message"); |
||||
public static String REDIS_EVENT_TOPIC_SEND = "socket:event:send"; |
||||
public static int REDIS_EVENT_SPECIFIC = 0; |
||||
public static int REDIS_EVENT_BROADCAST = 1; |
||||
public static int REDIS_EVENT_LOGOUT = 2; |
||||
|
||||
public static String REDIS_ONLINE_NUM = "socket:online-num"; |
||||
public static String REDIS_ONLINE_USER = "socket:online-user"; |
||||
|
||||
public static final String EVENT_LOGOUT = "logout"; |
||||
public static final String EVENT_NEW_MESSAGE = "new-message"; |
||||
} |
||||
|
||||
@ -1,115 +1,89 @@ |
||||
package com.toesbieya.my.controller; |
||||
|
||||
import com.toesbieya.my.enumeration.RecLoginHistoryEnum; |
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import com.toesbieya.my.model.vo.update.UserUpdatePwd; |
||||
import com.toesbieya.my.service.RecService; |
||||
import com.toesbieya.my.service.SysUserService; |
||||
import com.toesbieya.my.model.vo.LoginParam; |
||||
import com.toesbieya.my.model.vo.PasswordUpdateParam; |
||||
import com.toesbieya.my.model.vo.RegisterParam; |
||||
import com.toesbieya.my.model.vo.UserVo; |
||||
import com.toesbieya.my.service.AccountService; |
||||
import com.toesbieya.my.utils.IpUtil; |
||||
import com.toesbieya.my.utils.Result; |
||||
import com.toesbieya.my.utils.Util; |
||||
import org.springframework.util.DigestUtils; |
||||
import com.toesbieya.my.utils.SessionUtil; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.annotation.Resource; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpSession; |
||||
import javax.validation.Valid; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.net.URLDecoder; |
||||
import java.util.Map; |
||||
|
||||
@RestController |
||||
@RequestMapping("account") |
||||
public class AccountController { |
||||
@Resource |
||||
private SysUserService userService; |
||||
|
||||
@Resource |
||||
private RecService recService; |
||||
|
||||
@Resource |
||||
private HttpSession session; |
||||
private AccountService accountService; |
||||
|
||||
@PostMapping("login") |
||||
public Result login(HttpServletRequest request, @RequestBody Map<String, String> map) { |
||||
String username = map.get("username"); |
||||
String password = map.get("password"); |
||||
String err = validate(username, password); |
||||
if (err != null) return Result.fail(err); |
||||
|
||||
return userService.login(username, password, IpUtil.getIp(request)); |
||||
} |
||||
|
||||
@PostMapping("register") |
||||
public Result register(@RequestBody Map<String, String> map) { |
||||
String username = map.get("username"); |
||||
String password = map.get("password"); |
||||
String err = validate(username, password); |
||||
if (err != null) return Result.fail(err); |
||||
|
||||
return userService.register(username, password); |
||||
public Result login(HttpServletRequest request, @Valid @RequestBody LoginParam param) { |
||||
return accountService.login(param, IpUtil.getIp(request)); |
||||
} |
||||
|
||||
@GetMapping("logout") |
||||
public Result logout(HttpServletRequest request) { |
||||
SysUser user = Util.getUser(); |
||||
if (user != null) { |
||||
recService.insertLoginHistory(user, IpUtil.getIp(request), RecLoginHistoryEnum.LOGOUT); |
||||
} |
||||
session.invalidate(); |
||||
return Result.success("登出成功"); |
||||
UserVo user = SessionUtil.get(); |
||||
return accountService.logout(user, IpUtil.getIp(request)); |
||||
} |
||||
|
||||
@PostMapping("register") |
||||
public Result register(@Valid @RequestBody RegisterParam param) { |
||||
return accountService.register(param); |
||||
} |
||||
|
||||
@PostMapping("updatePwd") |
||||
public Result updatePwd(@RequestBody UserUpdatePwd vo) { |
||||
SysUser user = Util.getUser(); |
||||
vo.setId(user.getId()); |
||||
public Result updatePwd(@RequestBody PasswordUpdateParam param) { |
||||
UserVo user = SessionUtil.get(); |
||||
param.setId(user.getId()); |
||||
|
||||
String errMsg = validateUpdatePwdParam(vo); |
||||
String errMsg = validateUpdatePwdParam(param); |
||||
if (errMsg != null) return Result.fail(errMsg); |
||||
|
||||
vo.setOld_pwd(DigestUtils.md5DigestAsHex(vo.getOld_pwd().getBytes())); |
||||
vo.setNew_pwd(DigestUtils.md5DigestAsHex(vo.getNew_pwd().getBytes())); |
||||
|
||||
return userService.updatePwd(vo); |
||||
return accountService.updatePwd(param); |
||||
} |
||||
|
||||
@GetMapping("updateAvatar") |
||||
public Result updateAvatar(@RequestParam String key) throws UnsupportedEncodingException { |
||||
if (StringUtils.isEmpty(key)) return Result.fail("参数错误"); |
||||
|
||||
return userService.updateAvatar(Util.getUser(), URLDecoder.decode(key, "utf-8"), Util.getSession()); |
||||
UserVo user = SessionUtil.get(); |
||||
return accountService.updateAvatar(user, URLDecoder.decode(key, "utf-8")); |
||||
} |
||||
|
||||
@GetMapping("validate") |
||||
public Result validate(@RequestParam String pwd) { |
||||
SysUser current = Util.getUser(); |
||||
if (!pwd.equals(current.getPwd())) return Result.fail("校验失败"); |
||||
UserVo current = SessionUtil.get(); |
||||
|
||||
if (!pwd.equals(current.getPwd())) { |
||||
return Result.fail("校验失败"); |
||||
} |
||||
|
||||
return Result.success("校验通过"); |
||||
} |
||||
|
||||
@GetMapping("checkName") |
||||
public Result checkName(@RequestParam String name) { |
||||
return Result.success(userService.checkName(name) ? null : "该用户名已存在"); |
||||
} |
||||
|
||||
private String validate(String username, String password) { |
||||
if ((StringUtils.isEmpty(username) |
||||
|| StringUtils.isEmpty(password) |
||||
|| username.length() > 20 |
||||
|| password.length() != 32)) { |
||||
return "用户名或密码输入有误"; |
||||
public Result checkName(@RequestParam(required = false) Integer id, @RequestParam String name) { |
||||
if (StringUtils.isEmpty(name)) { |
||||
return Result.success(); |
||||
} |
||||
return null; |
||||
|
||||
return Result.success(accountService.checkName(name, id) ? null : "该用户名已存在"); |
||||
} |
||||
|
||||
private String validateUpdatePwdParam(UserUpdatePwd vo) { |
||||
private String validateUpdatePwdParam(PasswordUpdateParam vo) { |
||||
if (vo.getId() == null) return "修改失败,参数错误"; |
||||
if (StringUtils.isEmpty(vo.getOld_pwd())) return "修改失败,原密码不能为空"; |
||||
if (StringUtils.isEmpty(vo.getNew_pwd())) return "修改失败,新密码不能为空"; |
||||
if (vo.getOld_pwd().equals(vo.getNew_pwd())) return "修改失败,新密码不得与旧密码相同"; |
||||
if (vo.getNew_pwd().length() < 6 || vo.getNew_pwd().length() > 32) return "修改失败,密码长度为6-32位"; |
||||
if (vo.getNew_pwd().length() != 32) return "修改失败,密码参数有误"; |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
@ -1,17 +0,0 @@ |
||||
package com.toesbieya.my.controller; |
||||
|
||||
import com.toesbieya.my.utils.MonitorUtil; |
||||
import com.toesbieya.my.utils.Result; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
@RestController |
||||
@RequestMapping("system/monitor") |
||||
public class MonitorController { |
||||
|
||||
@GetMapping("get") |
||||
public Result get() { |
||||
return Result.success(MonitorUtil.getMonitorInfo()); |
||||
} |
||||
} |
||||
@ -1,66 +1,45 @@ |
||||
package com.toesbieya.my.interceptor; |
||||
|
||||
import com.toesbieya.my.constant.SessionConstant; |
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import com.toesbieya.my.model.vo.UserVo; |
||||
import com.toesbieya.my.module.PermissionModule; |
||||
import com.toesbieya.my.module.request.RequestModule; |
||||
import com.toesbieya.my.utils.IpUtil; |
||||
import com.toesbieya.my.utils.Result; |
||||
import com.toesbieya.my.utils.ThreadUtil; |
||||
import com.toesbieya.my.utils.Util; |
||||
import com.toesbieya.my.utils.*; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.ModelAndView; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
|
||||
@Slf4j |
||||
public class SecurityInterceptor implements HandlerInterceptor { |
||||
|
||||
@Override |
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
||||
HttpSession httpSession = request.getSession(); |
||||
String url = request.getServletPath(); |
||||
String method = request.getMethod(); |
||||
String ip = IpUtil.getIp(request); |
||||
|
||||
if (!RequestModule.urlExistMapping(url, method)) { |
||||
Util.responseJson(response, Result.notfound()); |
||||
WebUtil.responseJson(response, Result.notfound()); |
||||
log.error("请求地址不存在:{},{},IP:{}", url, method, ip); |
||||
ThreadUtil.clearUser(); |
||||
return false; |
||||
} |
||||
|
||||
SysUser sysUser = Util.getUser(httpSession); |
||||
if (sysUser == null |
||||
|| request.getHeader(SessionConstant.TOKEN_KEY) == null |
||||
|| !request.getHeader(SessionConstant.TOKEN_KEY).equals(httpSession.getAttribute(SessionConstant.TOKEN_KEY))) { |
||||
Util.responseJson(response, Result.requireLogin()); |
||||
UserVo user = SessionUtil.get(request); |
||||
|
||||
if (user == null) { |
||||
WebUtil.responseJson(response, Result.requireLogin()); |
||||
ThreadUtil.clearUser(); |
||||
return false; |
||||
} |
||||
|
||||
if (!PermissionModule.authority(sysUser, url)) { |
||||
Util.responseJson(response, Result.noPermission()); |
||||
log.warn("权限拦截,访问路径:{},用户:{},IP:{}", url, sysUser.getName(), ip); |
||||
if (!PermissionModule.authority(user, url)) { |
||||
WebUtil.responseJson(response, Result.noPermission()); |
||||
log.warn("权限拦截,访问路径:{},用户:{},IP:{}", url, user.getName(), ip); |
||||
ThreadUtil.clearUser(); |
||||
return false; |
||||
} |
||||
|
||||
ThreadUtil.setUser(sysUser); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { |
||||
|
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,17 @@ |
||||
package com.toesbieya.my.model.vo; |
||||
|
||||
import lombok.Data; |
||||
import org.hibernate.validator.constraints.Length; |
||||
|
||||
import javax.validation.constraints.NotNull; |
||||
|
||||
@Data |
||||
public class LoginParam { |
||||
@NotNull(message = "用户名不能为空") |
||||
@Length(max = 20, message = "用户名太长了") |
||||
private String username; |
||||
|
||||
@NotNull(message = "密码不能为空") |
||||
@Length(min = 32, max = 32, message = "密码异常") |
||||
private String password; |
||||
} |
||||
@ -0,0 +1,26 @@ |
||||
package com.toesbieya.my.model.vo; |
||||
|
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.Map; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
public class LoginSuccessInfo { |
||||
private Integer id; |
||||
private String name; |
||||
private String role_name; |
||||
private String avatar; |
||||
private Integer admin; |
||||
private String token; |
||||
private Map<String, Integer> resources; |
||||
|
||||
public LoginSuccessInfo(SysUser user) { |
||||
this.id = user.getId(); |
||||
this.name = user.getName(); |
||||
this.avatar = user.getAvatar(); |
||||
this.admin = user.getAdmin(); |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@ |
||||
package com.toesbieya.my.model.vo; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class PasswordUpdateParam { |
||||
private Integer id; |
||||
private String new_pwd; |
||||
private String old_pwd; |
||||
} |
||||
@ -0,0 +1,11 @@ |
||||
package com.toesbieya.my.model.vo; |
||||
|
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.ToString; |
||||
|
||||
@Data |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class RegisterParam extends LoginParam { |
||||
} |
||||
@ -0,0 +1,33 @@ |
||||
package com.toesbieya.my.model.vo; |
||||
|
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.ToString; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@ToString(callSuper = true) |
||||
@EqualsAndHashCode(callSuper = true) |
||||
public class UserVo extends SysUser { |
||||
private String token; |
||||
private String role_name; |
||||
private boolean online = false; |
||||
private Set<Integer> resource_ids; |
||||
private Map<String, Integer> resource_map; |
||||
|
||||
public UserVo(SysUser parent) { |
||||
this.setId(parent.getId()); |
||||
this.setName(parent.getName()); |
||||
this.setPwd(parent.getPwd()); |
||||
this.setRole(parent.getRole()); |
||||
this.setAvatar(parent.getAvatar()); |
||||
this.setCtime(parent.getCtime()); |
||||
this.setAdmin(parent.getAdmin()); |
||||
this.setStatus(parent.getStatus()); |
||||
} |
||||
} |
||||
@ -1,54 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import oshi.hardware.CentralProcessor; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class CpuInfo { |
||||
//cpu名称
|
||||
private String name; |
||||
//核心数
|
||||
private int core; |
||||
//内核态CPU时间
|
||||
private double system; |
||||
//用户态CPU时间
|
||||
private double user; |
||||
//低优先级用户态CPU时间
|
||||
private double nice; |
||||
//空闲时间,不包括io等待时间
|
||||
private double idle; |
||||
//等待I/O的CPU时间
|
||||
private double ioWait; |
||||
//处理硬中断的CPU时间
|
||||
private double irq; |
||||
//处理软中断的CPU时间
|
||||
private double softIrq; |
||||
//运行在虚拟机中的时候,被其他虚拟机占用的CPU时间
|
||||
private double steal; |
||||
|
||||
public CpuInfo(CentralProcessor processor, long[] prevTicks, long[] ticks) { |
||||
this.name = processor.getProcessorIdentifier().getName().trim(); |
||||
this.core = processor.getLogicalProcessorCount(); |
||||
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; |
||||
long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; |
||||
long softIrq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; |
||||
long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; |
||||
long system = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; |
||||
long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; |
||||
long ioWait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; |
||||
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; |
||||
long total = user + nice + system + idle + ioWait + irq + softIrq + steal; |
||||
this.system = system * 1.0 / total * 100; |
||||
this.nice = nice * 1.0 / total * 100; |
||||
this.user = user * 1.0 / total * 100; |
||||
this.idle = idle * 1.0 / total * 100; |
||||
this.ioWait = ioWait * 1.0 / total * 100; |
||||
this.irq = irq * 1.0 / total * 100; |
||||
this.softIrq = softIrq * 1.0 / total * 100; |
||||
this.steal = steal * 1.0 / total * 100; |
||||
} |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import oshi.software.os.OSFileStore; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class DiskInfo { |
||||
private String name; |
||||
private long total; |
||||
private long used; |
||||
private long remain; |
||||
private double utilizationRate; |
||||
|
||||
public DiskInfo(OSFileStore fs) { |
||||
this.name = fs.getMount(); |
||||
this.total = fs.getTotalSpace(); |
||||
this.remain = fs.getUsableSpace(); |
||||
this.used = this.total - this.remain; |
||||
this.utilizationRate = this.used * 1.0 / this.total * 100; |
||||
} |
||||
} |
||||
@ -1,29 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class JvmInfo { |
||||
//jvm最大可申请内存
|
||||
private long max; |
||||
//jvm当前总内存
|
||||
private long total; |
||||
//已使用内存
|
||||
private long used; |
||||
//空闲内存
|
||||
private long remain; |
||||
//使用率
|
||||
private double utilizationRate; |
||||
|
||||
public JvmInfo(long max, long total, long remain) { |
||||
this.max = max; |
||||
this.total = total; |
||||
this.remain = remain; |
||||
this.used = total - remain; |
||||
this.utilizationRate = this.used * 1.0 / total * 100; |
||||
} |
||||
} |
||||
@ -1,26 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class MemoryInfo { |
||||
//总内存
|
||||
private long total; |
||||
//已使用内存
|
||||
private long used; |
||||
//剩余内存
|
||||
private long remain; |
||||
//内存使用率
|
||||
private double utilizationRate; |
||||
|
||||
public MemoryInfo(long total, long remain) { |
||||
this.total = total; |
||||
this.remain = remain; |
||||
this.used = total - remain; |
||||
this.utilizationRate = this.used * 1.0 / total * 100; |
||||
} |
||||
} |
||||
@ -1,20 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.List; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class MonitorInfo { |
||||
private OperatingInfo operatingInfo; |
||||
private CpuInfo cpuInfo; |
||||
private MemoryInfo memoryInfo; |
||||
private JvmInfo jvmInfo; |
||||
private List<DiskInfo> diskInfos; |
||||
private Long timestamp; |
||||
private Integer expire; |
||||
} |
||||
@ -1,19 +0,0 @@ |
||||
package com.toesbieya.my.model.vo.info; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import oshi.software.os.OperatingSystem; |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class OperatingInfo { |
||||
private long bootedTime; |
||||
private long upTime; |
||||
|
||||
public OperatingInfo(OperatingSystem os) { |
||||
this.bootedTime = os.getSystemBootTime(); |
||||
this.upTime = os.getSystemUptime(); |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@ |
||||
package com.toesbieya.my.module.redis; |
||||
|
||||
import java.io.Closeable; |
||||
|
||||
public interface LockHelper extends Closeable { |
||||
String LOCK_LUA_SCRIPT = "return redis.call('set',KEYS[1],ARGV[1],'EX',ARGV[2],'NX')"; |
||||
String UNLOCK_LUA_SCRIPT = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return false end"; |
||||
|
||||
@Override |
||||
void close(); |
||||
|
||||
boolean lock(); |
||||
|
||||
void unlock(); |
||||
} |
||||
@ -1,45 +0,0 @@ |
||||
package com.toesbieya.my.module.redis; |
||||
|
||||
import com.toesbieya.my.utils.RedisUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.data.redis.core.StringRedisTemplate; |
||||
import org.springframework.data.redis.core.script.DefaultRedisScript; |
||||
import org.springframework.data.redis.core.script.RedisScript; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Objects; |
||||
|
||||
@Slf4j |
||||
public class RedisLockHelper implements LockHelper { |
||||
private final StringRedisTemplate template = RedisUtil.getStringRedisTemplate(); |
||||
private final String key; |
||||
private final String value; |
||||
private final String expire; |
||||
|
||||
public RedisLockHelper(String key) { |
||||
this.key = "lock:" + key; |
||||
this.value = String.valueOf(System.currentTimeMillis()); |
||||
this.expire = "300"; |
||||
} |
||||
|
||||
@Override |
||||
public void close() { |
||||
unlock(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean lock() { |
||||
RedisScript<Boolean> redisScript = new DefaultRedisScript<>(LockHelper.LOCK_LUA_SCRIPT, Boolean.class); |
||||
Boolean result = template.execute(redisScript, Collections.singletonList(key), value, expire); |
||||
return Objects.equals(result, true); |
||||
} |
||||
|
||||
@Override |
||||
public void unlock() { |
||||
RedisScript<Boolean> redisScript = new DefaultRedisScript<>(LockHelper.UNLOCK_LUA_SCRIPT, Boolean.class); |
||||
Boolean result = template.execute(redisScript, Collections.singletonList(key), value); |
||||
if (result == null || !result) { |
||||
log.error("redis锁释放失败,key:{},value:{}", key, value); |
||||
} |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@ |
||||
package com.toesbieya.my.module.redis; |
||||
|
||||
public class RedisLockType { |
||||
public static final String UPDATE_DOCUMENT_ID = "UPDATE_DOCUMENTS"; |
||||
} |
||||
@ -0,0 +1,145 @@ |
||||
package com.toesbieya.my.service; |
||||
|
||||
import com.toesbieya.my.annoation.UserAction; |
||||
import com.toesbieya.my.enumeration.GeneralStatusEnum; |
||||
import com.toesbieya.my.enumeration.RecLoginHistoryEnum; |
||||
import com.toesbieya.my.mapper.SysUserMapper; |
||||
import com.toesbieya.my.model.entity.SysResource; |
||||
import com.toesbieya.my.model.entity.SysUser; |
||||
import com.toesbieya.my.model.vo.*; |
||||
import com.toesbieya.my.utils.QiniuUtil; |
||||
import com.toesbieya.my.utils.Result; |
||||
import com.toesbieya.my.utils.SessionUtil; |
||||
import com.toesbieya.my.utils.Util; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.util.*; |
||||
|
||||
@Service |
||||
public class AccountService { |
||||
@Resource |
||||
private SysUserMapper userMapper; |
||||
@Resource |
||||
private SysResourceService resourceService; |
||||
@Resource |
||||
private RecService recService; |
||||
|
||||
public Result login(LoginParam param, String ip) { |
||||
SysUser user = userMapper.getByNameAndPwd(param.getUsername(), param.getPassword()); |
||||
|
||||
if (user == null) { |
||||
return Result.fail("用户名或密码错误"); |
||||
} |
||||
if (user.getStatus() == GeneralStatusEnum.DISABLED.getCode()) { |
||||
return Result.fail("该用户已被禁用,请联系管理员"); |
||||
} |
||||
Integer roleId = user.getRole(); |
||||
if (user.getAdmin() != 1 && roleId == null) { |
||||
return Result.fail("该用户尚未被分配角色,请联系管理员"); |
||||
} |
||||
|
||||
//设置token
|
||||
String token = Util.UUID(); |
||||
|
||||
//存入redis的数据
|
||||
UserVo userVo = new UserVo(user); |
||||
userVo.setToken(token); |
||||
|
||||
//传递给前端的数据
|
||||
LoginSuccessInfo info = new LoginSuccessInfo(user); |
||||
info.setToken(token); |
||||
|
||||
Map<String, Integer> userResourcesUrlMap = null; |
||||
|
||||
Set<Integer> userResourcesIdSet = null; |
||||
|
||||
//获取用户的所有权限url
|
||||
if (roleId != null) { |
||||
List<SysResource> resources = resourceService.getByRole(user.getRole()); |
||||
|
||||
userResourcesUrlMap = new HashMap<>(128); |
||||
userResourcesIdSet = new HashSet<>(128); |
||||
|
||||
for (SysResource resource : resources) { |
||||
Integer resourceId = resource.getId(); |
||||
userResourcesUrlMap.put(resource.getUrl(), resourceId); |
||||
userResourcesIdSet.add(resourceId); |
||||
} |
||||
} |
||||
|
||||
userVo.setResource_ids(userResourcesIdSet); |
||||
|
||||
info.setResources(userResourcesUrlMap); |
||||
|
||||
//用户信息插入redis
|
||||
SessionUtil.save(userVo); |
||||
|
||||
//记录登陆信息
|
||||
recService.insertLoginHistory(userVo, ip, RecLoginHistoryEnum.LOGIN); |
||||
|
||||
return Result.success(info); |
||||
} |
||||
|
||||
public Result logout(UserVo user, String ip) { |
||||
if (user != null) { |
||||
recService.insertLoginHistory(user, ip, RecLoginHistoryEnum.LOGOUT); |
||||
SessionUtil.remove(user.getToken()); |
||||
} |
||||
|
||||
return Result.success("登出成功"); |
||||
} |
||||
|
||||
public Result register(RegisterParam param) { |
||||
String name = param.getUsername(); |
||||
|
||||
if (userMapper.isNameExist(name, null)) { |
||||
return Result.fail("该用户名称已存在"); |
||||
} |
||||
|
||||
SysUser user = new SysUser(); |
||||
user.setName(name); |
||||
user.setPwd(param.getPassword()); |
||||
user.setRole(1); |
||||
user.setStatus(GeneralStatusEnum.ENABLED.getCode()); |
||||
user.setCtime(System.currentTimeMillis()); |
||||
|
||||
userMapper.add(user); |
||||
|
||||
return Result.success("注册成功"); |
||||
} |
||||
|
||||
@UserAction("'修改密码'") |
||||
public Result updatePwd(PasswordUpdateParam param) { |
||||
int rows = userMapper.updatePwd(param); |
||||
return rows > 0 ? Result.success("修改成功") : Result.fail("修改失败,请检查原密码是否正确"); |
||||
} |
||||
|
||||
@UserAction("'修改头像'") |
||||
public Result updateAvatar(UserVo user, String avatar) { |
||||
int rows = userMapper.updateAvatar(user.getId(), avatar); |
||||
|
||||
//更新成功后删除云上旧的头像,同时更新redis中的用户信息
|
||||
if (rows > 0) { |
||||
String oldAvatar = user.getAvatar(); |
||||
if (!StringUtils.isEmpty(oldAvatar)) { |
||||
QiniuUtil.delete(oldAvatar); |
||||
} |
||||
|
||||
user.setAvatar(avatar); |
||||
SessionUtil.save(user); |
||||
|
||||
return Result.success("上传头像成功"); |
||||
} |
||||
|
||||
//否则删除此次上传至云的头像
|
||||
QiniuUtil.delete(avatar); |
||||
|
||||
return Result.fail("上传头像失败"); |
||||
} |
||||
|
||||
public boolean checkName(String name, Integer id) { |
||||
return !userMapper.isNameExist(name, id); |
||||
} |
||||
} |
||||
@ -0,0 +1,47 @@ |
||||
package com.toesbieya.my.utils; |
||||
|
||||
import com.google.common.io.ByteStreams; |
||||
import com.toesbieya.my.constant.DocumentConstant; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.data.redis.core.script.DefaultRedisScript; |
||||
import org.springframework.data.redis.core.script.RedisScript; |
||||
|
||||
import java.io.IOException; |
||||
import java.time.format.DateTimeFormatter; |
||||
import java.util.Arrays; |
||||
|
||||
@Slf4j |
||||
public class DocumentUtil { |
||||
private static String GET_DOCUMENT_ID_SCRIPT; |
||||
|
||||
static { |
||||
try { |
||||
GET_DOCUMENT_ID_SCRIPT = new String(ByteStreams.toByteArray(new ClassPathResource("/script/get_document_id.lua").getInputStream())); |
||||
} |
||||
catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
//获取单号,形如 {type}0001
|
||||
public static String getDocumentID(String type) { |
||||
if (!Arrays.asList(DocumentConstant.DOCUMENT_TYPE).contains(type)) { |
||||
log.error("单据类型有误,【{}】不存在", type); |
||||
return null; |
||||
} |
||||
|
||||
RedisScript<Long> redisScript = new DefaultRedisScript<>(GET_DOCUMENT_ID_SCRIPT, Long.class); |
||||
|
||||
Long result = RedisUtil.execute( |
||||
redisScript, |
||||
Arrays.asList(DocumentConstant.DOCUMENT_TYPE_REDIS_KEY, DocumentConstant.DOCUMENT_TYPE_REDIS_KEY), |
||||
String.valueOf(DateUtil.getTimestampNow()), |
||||
type |
||||
); |
||||
|
||||
if (result == null || result <= 1) return null; |
||||
|
||||
return String.format("%s%s%04d", type, DateUtil.dateFormat(DateTimeFormatter.BASIC_ISO_DATE), result - 1); |
||||
} |
||||
} |
||||
@ -1,69 +0,0 @@ |
||||
package com.toesbieya.my.utils; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.toesbieya.my.model.vo.info.*; |
||||
import com.toesbieya.my.model.vo.info.*; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import oshi.SystemInfo; |
||||
import oshi.hardware.CentralProcessor; |
||||
import oshi.hardware.GlobalMemory; |
||||
import oshi.software.os.FileSystem; |
||||
import oshi.software.os.OSFileStore; |
||||
import oshi.software.os.OperatingSystem; |
||||
import oshi.util.Util; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
@Slf4j |
||||
public class MonitorUtil { |
||||
private final static String REDIS_MONITOR_INFO_KEY = "SYSTEM_MONITOR_INFO_CACHE"; |
||||
private final static int EXPIRE = 30; |
||||
private final static SystemInfo SYSTEM_INFO = new SystemInfo(); |
||||
|
||||
public static MonitorInfo getMonitorInfo() { |
||||
long timestamp = System.currentTimeMillis(); |
||||
JSONObject cache = (JSONObject) RedisUtil.get(REDIS_MONITOR_INFO_KEY); |
||||
if (cache == null) { |
||||
MonitorInfo monitorInfo = new MonitorInfo(getOperatingInfo(), getCpuInfo(), getMemoryInfo(), getJvmInfo(), getDiskInfo(), timestamp, EXPIRE); |
||||
RedisUtil.set(REDIS_MONITOR_INFO_KEY, monitorInfo, EXPIRE); |
||||
return monitorInfo; |
||||
} |
||||
else { |
||||
return JSONObject.toJavaObject(cache, MonitorInfo.class); |
||||
} |
||||
} |
||||
|
||||
private static OperatingInfo getOperatingInfo() { |
||||
OperatingSystem os = SYSTEM_INFO.getOperatingSystem(); |
||||
return new OperatingInfo(os); |
||||
} |
||||
|
||||
private static CpuInfo getCpuInfo() { |
||||
CentralProcessor processor = SYSTEM_INFO.getHardware().getProcessor(); |
||||
long[] prevTicks = processor.getSystemCpuLoadTicks(); |
||||
Util.sleep(1000); |
||||
long[] ticks = processor.getSystemCpuLoadTicks(); |
||||
return new CpuInfo(processor, prevTicks, ticks); |
||||
} |
||||
|
||||
private static MemoryInfo getMemoryInfo() { |
||||
GlobalMemory memory = SYSTEM_INFO.getHardware().getMemory(); |
||||
return new MemoryInfo(memory.getTotal(), memory.getAvailable()); |
||||
} |
||||
|
||||
private static JvmInfo getJvmInfo() { |
||||
Runtime runtime = Runtime.getRuntime(); |
||||
return new JvmInfo(runtime.maxMemory(), runtime.totalMemory(), runtime.freeMemory()); |
||||
} |
||||
|
||||
private static List<DiskInfo> getDiskInfo() { |
||||
FileSystem fileSystem = SYSTEM_INFO.getOperatingSystem().getFileSystem(); |
||||
OSFileStore[] fsArray = fileSystem.getFileStores(); |
||||
List<DiskInfo> list = new ArrayList<>(); |
||||
for (OSFileStore fs : fsArray) { |
||||
list.add(new DiskInfo(fs)); |
||||
} |
||||
return list; |
||||
} |
||||
} |
||||
@ -0,0 +1,46 @@ |
||||
package com.toesbieya.my.utils; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.toesbieya.my.constant.SessionConstant; |
||||
import com.toesbieya.my.model.vo.UserVo; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
public class SessionUtil { |
||||
private static long expire = 3600 * 8; |
||||
|
||||
public static void remove(String token) { |
||||
if (StringUtils.isEmpty(token)) return; |
||||
|
||||
RedisUtil.expireImmediately(SessionConstant.REDIS_NAMESPACE + token); |
||||
} |
||||
|
||||
public static void save(UserVo user) { |
||||
String token = user.getToken(); |
||||
|
||||
if (StringUtils.isEmpty(token)) return; |
||||
|
||||
RedisUtil.set(SessionConstant.REDIS_NAMESPACE + token, user, expire); |
||||
} |
||||
|
||||
public static UserVo get() { |
||||
UserVo user = ThreadUtil.getUser(); |
||||
return user == null ? get(WebUtil.getRequest()) : user; |
||||
} |
||||
|
||||
public static UserVo get(String token) { |
||||
if (StringUtils.isEmpty(token)) return null; |
||||
|
||||
JSONObject o = (JSONObject) RedisUtil.get(SessionConstant.REDIS_NAMESPACE + token); |
||||
|
||||
if (o == null) return null; |
||||
|
||||
return JSONObject.toJavaObject(o, UserVo.class); |
||||
} |
||||
|
||||
public static UserVo get(HttpServletRequest request) { |
||||
String token = request.getHeader(SessionConstant.TOKEN_KEY); |
||||
return get(token); |
||||
} |
||||
} |
||||
@ -0,0 +1,23 @@ |
||||
package com.toesbieya.my.utils; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.util.Objects; |
||||
|
||||
public class WebUtil { |
||||
public static void responseJson(HttpServletResponse response, Result result) throws IOException { |
||||
response.setCharacterEncoding("UTF-8"); |
||||
response.setContentType("application/json; charset=utf-8"); |
||||
|
||||
response.getWriter().print(JSON.toJSONString(result)); |
||||
} |
||||
|
||||
public static HttpServletRequest getRequest() { |
||||
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue