4.03

都4月了,博客园还在自查,证明技术型Blog加评论功能纯粹多此一举。
QQ图片20210403173318.png

4.04

翻网上的SpringBoot的源码分析资料,发现源码的样子和最新版长得有多处不同,这就是快速迭代的力量吗。。。。看的是2.2.0,我用的是2.4.4。
在META-INF的spring.factories里,# Initializers没了(好),第一行是# Logging Systems,嗯。# Auto Configure也没有???
然后发现我眼花了,在spring-boot-autoconfigure-2.4.4.jar里,我怎么点进了spring-boot-2.4.4.jar,点进正确的包后全看到了233
老师这里还口误了,对着@Configuration说这是Java的配置类(Spring:???)
在源码里跳一下,从WebMvcAutoConfiguration.java跳到WebMvcProperties,没看到视频里的private String DateFormat;,有幸还能看到private String staticPathPattern = “/**”;,哒哒哒。
private final Servlet servlet = new Servlet();
private final View view = new View();
这两行在视频里是在staticPathPattern下面的,到我电脑上跑到。。。。眼花,还是在下面。
在SpringFactoriesLoader里面的loadFactorie,多了一个if循环,好家伙。
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
通过学习Spring,我真正意识到思维导图的重要性,在源码里面Ctrl+鼠标翻来翻去实在是为难我一个没学过Spring的萌新。
我第一次还眼花了,点进去AutoConfigurationPackage里怎么是@Import(Registrar.class),复盘时看了看,好家伙,变成@Import(AutoConfigurationPackages.Registrar.class)了,就说这里怎么会改,烫烫烫烫。
画思维导图冷不丁窜出来这两条弹幕,笑喷了。
Screenshot_20210405-155136(1).jpg
SpringFactoriseLoader里面,loadSpringFactories方法里,只有Enumeration urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);了,只能说是获取项目资源,获取系统资源那行代码没了。
然后我的AopAutoConfiguration.java和视频长得不一样,@ConditionalOnClass那行无了,视频还说这是核心注解之一,干,不过他是用这个当例子,影响不大。
这大概就是我在看自动配置原理初探时的一些碎碎念吧,蛮尬的233.

4.05

随便做一个起码我看的懂的思维导图,老师那个我都给绕晕了。 博客第二期 2021.04 - 图3HttpEncodingAutoConfiguration的分析我就不做思维导图了,视频长度太狗了。视频里的源码中,HttpEncodingAutoConfiguration()的参数还叫HttpProperties,到我这变成ServerProperties,真能迭代。自然地,所谓的spring.http的前缀,就是prefix嘛,里面的东西全变了,还是用server的prefix才行,换了绑定的prefix不能强改。
O3A{OGI%8P{T2ONXX6OM8$N.png
然后呢,spring.mvc.date-format变成了spring.mvc.format.date,这个开源项目的东西,过时还挺快的。。。问题是,视频中WebMvcAutoConfigurationAdapter里,头上那么大一个EnableConfigurationProperties。。。。居然不是@ConditionalOnxxx了,大意了,又眼花,以为没有。

4.06

addResourceHandlers()在视频里在WebMvcAutoConfiguration的第298行,跑到我这变成第400行,我这边的方法还多了一行super.addResourceHandlers(registry),狗啊。
WebMvcAutoConfigurationAdapter方法的第一个参数从ResourceProperties变成了WebProperties。
看MVC配置原理和SpringMVC扩展时我感慨了一下,这源码都哪到哪,更新后大变样。
“如果我们要扩展springmvc, 官方建议我们这样去做!”如何看待手撕SpringBoot源码撕了一个月?官方建议我们看待Rob要二八开。 博客第二期 2021.04 - 图5spring.mvc.date-format这个properties的配置过时了,尝试换成spring.mvc.format.date,都是自定义的配置日期格式化
然后我一直好奇怎么在IDEA里搜索某个jar包,就是跳转到外部库指定目录那种,回头问问。玩Eclipse没这么多包,没试过这种需求。
资料做项目用的静态资源,还是用的Bookstrap4.0,官网都Bookstrap5.0了,虽然是beta3,好歹最新稳定版是Bookstrap4.6,推荐Bookstrap5.0。
无数据库写Employee的Dao时,整一句employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));把我逗乐了,知道这是为了外键约束,不过第一眼看过去没注意自增的话,看着像面对面快传是真的好笑。

QQ图片20210406212445.jpg

  1. //增加一个员工
  2. public void save(Employee employee){
  3. if (employee.getId()==null){
  4. employee.setId(initId++);
  5. }
  6. employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
  7. employees.put(employee.getId(),employee);
  8. }

然后我意识到一个骚问题,资料的Dao里为什么要写业务逻辑,真写不应该来个DAOImpl吗,老师说话真没逻辑。
不过毕竟没有连接数据库,用Java类实现了伪数据罢了。
悲报,resolveLocale变成。。。眼瞎了,我刚刚怎么跑到Context那个上下文相关类里面Ctrl+F,成功眼花,先回到AcceptHeaderLocaleResolver.java里。

  1. @Override
  2. public Locale resolveLocale(HttpServletRequest request) {
  3. Locale defaultLocale = getDefaultLocale();
  4. if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
  5. return defaultLocale;
  6. }
  7. Locale requestLocale = request.getLocale();
  8. List<Locale> supportedLocales = getSupportedLocales();
  9. if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
  10. return requestLocale;
  11. }
  12. Locale supportedLocale = findSupportedLocale(request, supportedLocales);
  13. if (supportedLocale != null) {
  14. return supportedLocale;
  15. }
  16. return (defaultLocale != null ? defaultLocale : requestLocale);
  17. }

然后写MyLocaleResolver时,就是继承一下LocaleResolver重写AcceptHeaderLocaleResolver时,StringUtils.isEmpty()这个方法过时了,low啊,欧美速度(大嘘),改成hasText()。

  1. @Deprecated
  2. public static boolean isEmpty(@Nullable Object str) {
  3. return (str == null || "".equals(str));
  4. }

4.07

老实说,我有点理解不了SpringBoot里国际化的原理,想问问emmm
在登录功能实现那里,嗯,
@RequestParam和那个@ResponseBody的区别是啥,作用是啥。。。。Model和他的方法addAttribute()又是怎么实现的,我点进去方法一句话都没有,就一个接口(没学Spring)
为什么Controller层return的页面,比如index不需要加.html。。。。。。
今日离谱,实现login(
@RequestParam(“username”) String username,
@RequestParam(“password”) String password,
Model model)这个方法时我一直无法跳转,以为哪里有问题,然后发现离谱的地方,hastext()就是有这个问题,使用过时的isEmpty()就正常跳转到dashboard.html,我人傻了。

  1. public static boolean hasText(@Nullable CharSequence str) {
  2. return (str != null && str.length() > 0 && containsText(str));
  3. }
  1. public static boolean hasText(@Nullable String str) {
  2. return (str != null && !str.isEmpty() && containsText(str));
  3. }
  1. public static boolean isEmpty(@Nullable Object str) {
  2. return (str == null || "".equals(str));
  3. }

小丑竟是我自己🤡,函数对应的ture和false刚好反过来,之前看WebMvcConfiguration时我居然没看到,害。
Controller层那句return “dashboard”;改成return “redirect:/main.html”;是啥。。。。
LoginHandlerInterceptor为什么只需要实现接口的一个方法,另外两个呢,还有request.getSession().getAttribute(“loginUser”);理解不来。
意识到LoginController里,Model和HttpSession什么时候传进去的???
LoginHandlerInterceptor里那个request.getRequestDispatcher(“/index.html”).forward(request,response);,理解不来。
搜索时看到一段话,
二、/ 和 /**
/
是拦截所有的文件夹,不包含子文件夹
/** 是拦截所有的文件夹及里面的子文件夹
拦截完所有文件夹还不包含拦截了子文件夹?啥玩意?
今天把玩了Edge的F12,还是有禁用缓存的,不过我在application.propertise(好奇为什么资料不用yaml,前面铺垫这么多)配过spring.thymeleaf.cache=false了,这个倒没用了。
今天没能实现登录拦截器,挺遗憾的,莫名其妙实现addInterceptors()后main.html报404,什么鬼。
我贴代码块观察一下,下午就是这么解决的。

  1. public class LoginHandlerInterceptor implements HandlerInterceptor {
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse
  4. response, Object handler) throws Exception {
  5. // 获取 loginUser 信息进行判断
  6. Object user = request.getSession().getAttribute("loginUser");
  7. if (user == null){ // 未登录,返回登录页面
  8. request.setAttribute("msg","没有权限,请先登录");
  9. request.getRequestDispatcher("/index.html").forward(request,response);
  10. return false;
  11. }else {
  12. // 登录,放行
  13. return true;
  14. }
  15. }
  16. }
  1. public class LoginHandlerInterceptor implements HandlerInterceptor {
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  4. //登陆成功之后, 应该有用户的sessoin;
  5. Object loginUser = request.getSession().getAttribute("loginUser");
  6. if (loginUser == null) { //没有登录
  7. request.setAttribute("msg", "没有权限, 请先登录");
  8. request.getRequestDispatcher("/index.html").forward(request, response);
  9. return false;
  10. } else {
  11. return true;
  12. }
  13. }
  14. }

然后回看了一遍登录拦截器,发现在上一节登录功能实现我敲少了一行registry.addViewController(“/index.html”).setViewName(“index”);,心态崩了,没学springMVC也太难发现这种问题了。
QQ图片20210407235100.png
1.png
2.png
今天数据结构的课,不知道是不是因为教室的C语言编译器坏了(原先就是VC6.0,离谱,机房都是VS2010,一个几十年前的编译器一个十年前的编译器,半斤八两),老师现场百度并下载VS企业版6.0(头一遭知道Visual Stdio Enterprise 6.0这种东西,居然还能百度出序列码更离谱)。今天还是跌跌撞撞讲完树(此处特指二叉树)了。
然后就是IntelliJ更新到了2021-01(好耶)
MySQL Installer这软件是真邪门,每天凌晨0点准时弹命令行出来检查更新,监督大学生睡觉质量是吧😓

4.08

“Vue没听的人是理解不了这个的”(指把侧边栏的内容从dashboard.html抽出到common.html中),我寻思你也没用Vue来进行前后端分离啊,SpringBoot+Thymeleaf的模板引擎完成全套设计emmm
“所谓实现代码的复用,就是最好的”(类似可维护性和可扩展性)
在实现字段高亮判断的时候,给sidebar上的字上个参数来判断,

。我寻思fragment到底是啥还能传参数,thymeleaf官方文档基本没说,欺负英语学渣还是逼人去学Vue(
thymeleaf语法这么像java,的确是后端友好的模板引擎。
离谱,说class=”nav-link active”改成th:class=”${active==’main.html’?’nav-link active’:’nav-link’就能被thymeleaf接管,有th:class这个东西?
屏幕截图 2021-04-08 185307.png
百度了一下,th:class这个叫动态添加class样式(它98年的,我玩不过它)。
又是深夜这个时间点,我卡在员工管理系统的展示员工列表这,首先我不会Rectful风格(成功被吊),然后测试的时候报error,没办法在员工管理那一级拿到数据。。。。。。。
2021-04-08 23:58:10.759 ERROR 1864 —- [nio-8080-exec-1] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/kuang/emps] and exception [] as the response has already been committed. As a result, the response may have the wrong status code.

4.09

过了一天半,昨天的展示员工信息还是没有解决员工管理页面的信息丢失404问题,重新看,先还原一下之前的准备工作
common.html第50行th:class=”${active==’list.html’?’nav-link active’:’nav-link’}”改成 th:class=”nav-link”
common.html第22行th:class=”${active==’main.html’?’nav-link active’:’nav-link’}”改成th:class=”nav-link active”
嗯,然后注意到list.html有句