Spring Boot自定义登录视图无法识别求助(无需覆盖资源处理器)
错误信息
此应用程序没有针对/error的显式映射,因此您看到的是回退页面。
2023年1月29日 23:34:52 ART
发生意外错误(类型=未找到,状态=404)。
无可用消息
问题描述
我想替换Spring Security的默认登录模板,使用自制的自定义登录页面。但IDE(IntelliJ IDEA)和Spring均无法识别该视图,仅在LoginConfiguration.java中添加以下配置后才可正常运行:
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); }
但我认为覆盖默认资源处理器是不良实践,希望找到无需覆盖默认资源处理器的方法,让IDE和Spring都能识别我的视图。
当前配置代码
application.properties
server.port=8081 spring.datasource.url=jdbc:XX spring.datasource.username=Y spring.datasource.password =Z spring.jpa.hibernate.ddl-auto=update spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql=true spring.web.resources.static-locations=classpath:/static/ spring.mvc.view.prefix=/static/ spring.mvc.view.suffix=.html
LoginController.java
@GetMapping("/sarasa") public ModelAndView sarasa() { var mav = new ModelAndView(); mav.setViewName("login-form"); return mav; }
补充说明
我希望Spring Boot从src/main/resources/static目录获取文件,尝试过resources/WEB-INF、WEB-INF/classes/、resources/templates/等目录,且未使用任何模板引擎(如Thymeleaf),因之后计划对接React。查阅相关帖子均未解决问题。
自定义登录页面代码(login-form.html)
<!DOCTYPE html> <html lang="es"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Login</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script> <style> .login-form { width: 340px; margin: 50px auto; font-size: 15px; } .login-form form { margin-bottom: 15px; background: #f7f7f7; box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); padding: 30px; } .login-form h2 { margin: 0 0 15px; } .form-control, .btn { min-height: 38px; border-radius: 2px; } .btn { font-size: 15px; font-weight: bold; } </style> </head> <body> <div class="login-form"> <form action="/login" method="post"> <h2 class="text-center">Log in</h2> <div class="form-group"> <input type="text" name="username" class="form-control" placeholder="Username"> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Password"> </div> <div class="form-group"> <button type="submit" class="btn btn-primary btn-block">Log in</button> </div> </form> </div> </body> </html>
解决方案
1. 修正application.properties配置
删除以下两行多余配置:
spring.web.resources.static-locations=classpath:/static/ spring.mvc.view.prefix=/static/
Spring Boot默认已将classpath:/static/作为静态资源根目录,无需手动指定;而spring.mvc.view.prefix=/static/会导致视图解析器与静态资源处理器冲突,无法正确识别静态HTML文件。
保留spring.mvc.view.suffix=.html即可。
2. 调整视图访问逻辑
由于未使用模板引擎,无需通过Controller转发,可直接通过静态资源路径访问登录页面,同时在Spring Security配置中指定登录页面路径:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login-form.html") // 直接指向static目录下的HTML文件 .loginProcessingUrl("/login") // 与登录表单的action属性对应 .permitAll(); }
如果需要通过Controller返回页面,可简化Controller代码:
@GetMapping("/sarasa") public String sarasa() { return "forward:/login-form.html"; }
3. 让IntelliJ IDEA识别静态资源目录
右键src/main/resources/static目录,选择Mark Directory as -> Resources Root,IDE会自动索引该目录下的文件,解决识别问题。
内容的提问来源于stack exchange,提问作者Gdepablo

