若依架构代码改造
概述
若依架构是开源优秀版本,实现前后端分类,主要相关文档链接如下:https://doc.ruoyi.vip/ruoyi/
问题汇总和处理
尝试用若依架构改造本地项目,遇到问题汇总,便于大家参考交流
问题1、登录提示验证码有误:
解决:替换项目的时候,主要framework项目这个文件CaptchaConfig.java,如下行配置:KaptchaTextCreator一定带上空间名称逻辑,否则找不到
// 验证码文本生成器 properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator");
问题2、token存储redis缓存里面的json,结果取值反序列化失败:
解决:主要替换common模块里面Constants.java,修改配置如下,JSON_WHITELIST_STR 一定要配置自己的命名空间
/** * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) */ public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" }; /** * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) */ public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" }; /** * 定时任务违规的字符 */ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
问题3、mapper找不到,提示无此class文件。
解决:主要替换framework项目里面ApplicationConfig.java文件里面的注解,MapperScan一定改成自己的命名空间
/** * 程序注解配置 * * @author fts */ @Configuration // 表示通过aop框架暴露该代理对象,AopContext能够访问 @EnableAspectJAutoProxy(exposeProxy = true) // 指定要扫描的Mapper类的包的路径 @MapperScan("com.ruoyi.**.mapper") public class ApplicationConfig { /** * 时区配置 */ @Bean public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() { return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); } }
建议4:建议修改下CacheConstants.java文件修改成自己的项目后缀,如下,方便键值分开;
/** * 登录用户 redis key */ public static final String LOGIN_TOKEN_KEY = "login_tokens_test:";
常遇到问题列表:
1、Long 类型id,查询显示页面丢失精度显示不一致。需要加上注解:
@JsonSerialize(using = ToStringSerializer.class) private Long id;
2、mapper的查询日志显示不出来,配置文件加上如下:
# mybatis配置
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3、提示数据未授权,其他模块有效的token,到某个模块跟日志提示:token无效
解决方式:修改nacos配置文件,redis配置中和其他模块保持一致。
比如如下配置,其他模块都抱持统一:(spring.redis.database标识redis缓存数据库的编号,否则找其他数据库就会报错,找不到token)
4、若依页面集成
1>、菜单配置。不要用外部链接,配置如下:
2>、编写iframe/index目录下的vue(接受路由传过来的参数,用iframe加载url)
<template > <div> <iframe ref="tagFrame" width="100%" border="0" ></iframe> </div> </template> <script> import { getToken } from "@/utils/auth"; export default { name: "fts", data() { return { tagQuery:null }; }, mounted(){ this.loadFrameUrl(); }, created() { this.tagQuery=this.$route.query; }, methods: { /** 加载基础数据 */ loadFrameUrl() { const iframe = this.$refs.tagFrame; const url=this.tagQuery.tagUrl+"?tms_org=0001&source=" console.log(url) const deviceWidth = document.documentElement.clientWidth const deviceHeight = document.documentElement.clientHeight // 数字是页面布局宽度差值 //iframe.style.width = (Number(deviceWidth) - 40) + 'px' // 数字是页面布局高度差 iframe.style.height = (Number(deviceHeight) - 90) + 'px' this.openWindowFileHeader(iframe,url); }, //打开上传文件 openWindowFileHeader(iframe,url){ fetch(url, { headers: { 'UserInfo': getToken() // 添加自定义请求头 } }) .then(response => response.text()) .then(html => { iframe.contentWindow.document.open(); iframe.contentWindow.document.write(html); iframe.contentWindow.document.close(); }); } } }; </script>
3>、集成第三方地址后端java关键性的代码
String jwt = request.getHeader(JWT_TOKEN_HEADER);//获取token //解析token。采用 Claims claims = Jwts.parser().setSigningKey(generateKey()) .parseClaimsJws(jwt).getBody(); //基于jjwt和密钥,生成key private Key generateKey() { return new SecretKeySpec(jwtSecret.getBytes(), SignatureAlgorithm.HS512.getJcaName()); }
jjwt对应的pom文件
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency>