英文:
can't add HTML/CSS
问题
I didn't think I'd ask about this, but I can't connect HTML and CSS, and everything works strangely in general. What to do?
当Spring应用程序正在运行时,当访问其地址时,我的HTML页面可以正常工作,但没有CSS。当我单独在服务器上运行HTML页面时,会显示"404 Not Found"错误。但当我在VS Code中单独运行页面时,CSS可以正常工作。而在最后一个具有与我的相同包结构的应用程序中,也可以正常工作,但只是Spring版本不同,可能有一些依赖项不同。也许你有什么想法?
HTML
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/registration.css">
<link rel="stylesheet" type="text/css" href="../static/css/registration.css">
<title>Register page</title>
</head>
<body>
<div class="login">
<div class="login-triangle"></div>
<h2 class="login-header">Registration</h2>
<form th:method="POST" th:action="@{/auth/registration}"
th:object="${person}" class="login-container">
<p>
<input type="text" placeholder="Username" th:field="*{username}" id="username">
<div style="color:red" th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username Error</div>
</p>
<p><input type="email" placeholder="Email"
th:field="*{email}" id="email">
<div style="color:red" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</div></p>
<p><input type="password" placeholder="Password"
th:field="*{password}" id="password">
<div style="color:red" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</div></p>
<p><input type="submit" value="Register"></p>
</form>
</div>
</body>
</html>
CSS
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700);
body {
background: #456;
font-family: 'Open Sans', sans-serif;
}
.login {
width: 400px;
margin: 16px auto;
font-size: 16px;
}
/* Reset top and bottom margins from certain elements */
.login-header,
.login p {
margin-top: 0;
margin-bottom: 0;
}
/* The triangle form is achieved by a CSS hack */
.login-triangle {
width: 0;
margin-right: auto;
margin-left: auto;
border: 12px solid transparent;
border-bottom-color: #28d;
}
.login-header {
background: #28d;
padding: 20px;
font-size: 1.4em;
font-weight: normal;
text-align: center;
text-transform: uppercase;
color: #fff;
}
.login-container {
background: #ebebeb;
padding: 12px;
}
/* Every row inside .login-container is defined with p tags */
.login p {
padding: 12px;
}
.login input {
box-sizing: border-box;
display: block;
width: 100%;
border-width: 1px;
border-style: solid;
padding: 16px;
outline: 0;
font-family: inherit;
font-size: 0.95em;
}
.login input[type="email"],
.login input[type="password"] {
background: #fff;
border-color: #bbb;
color: #555;
}
/* Text fields' focus effect */
.login input[type="email"]:focus,
.login input[type="password"]:focus {
border-color: #888;
}
.login input[type="submit"] {
background: #28d;
border-color: transparent;
color: #fff;
cursor: pointer;
}
.login input[type="submit"]:hover {
background: #17c;
}
/* Buttons' focus effect */
.login input[type="submit"]:focus {
border-color: #05a;
}
POM (Maven Project Object Model)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringSecurityReturn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringSecurityReturn</name>
<description>SpringSecurityReturn</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</
<details>
<summary>英文:</summary>
I didn't think I'd ask about this, but I can't connect html and css, and everything works strangely in general. What to do?
When Spring application is working, my html page works when going to its address, but without CSS, when I run the html page separately, not on the server, the error "404 Not Found" is shown, when I run the page separately in VS Code, CSS works, and in the last application that has the same package structure as mine the current one also works as it should, but it differs only in the Spring version and may be some dependencies, maybe you will have ideas?
github:https://github.com/NikitaMozolevsky/SpringSecurityReturnUpdate
HTML
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/registration.css">
<link rel="stylesheet" type="text/css" href="../static/css/registration.css">
<title>Register page</title>
</head>
<body>
<div class="login">
<div class="login-triangle"></div>
<h2 class="login-header">Registration</h2>
<form th:method="POST" th:action="@{/auth/registration}"
th:object="${person}" class="login-container">
<p>
<input type="text" placeholder="Username" th:field="*{username}" id="username">
<div style="color:red" th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username Error</div>
</p>
<p><input type="email" placeholder="Email"
th:field="*{email}" id="email">
<div style="color:red" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</div></p>
<p><input type="password" placeholder="Password"
th:field="*{password}" id="password">
<div style="color:red" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</div></p>
<p><input type="submit" value="Register"></p>
</form>
</div>
</body>
</html>
CSS
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700);
body {
background: #456;
font-family: 'Open Sans', sans-serif;
}
.login {
width: 400px;
margin: 16px auto;
font-size: 16px;
}
/* Reset top and bottom margins from certain elements */
.login-header,
.login p {
margin-top: 0;
margin-bottom: 0;
}
/* The triangle form is achieved by a CSS hack */
.login-triangle {
width: 0;
margin-right: auto;
margin-left: auto;
border: 12px solid transparent;
border-bottom-color: #28d;
}
.login-header {
background: #28d;
padding: 20px;
font-size: 1.4em;
font-weight: normal;
text-align: center;
text-transform: uppercase;
color: #fff;
}
.login-container {
background: #ebebeb;
padding: 12px;
}
/* Every row inside .login-container is defined with p tags */
.login p {
padding: 12px;
}
.login input {
box-sizing: border-box;
display: block;
width: 100%;
border-width: 1px;
border-style: solid;
padding: 16px;
outline: 0;
font-family: inherit;
font-size: 0.95em;
}
.login input[type="email"],
.login input[type="password"] {
background: #fff;
border-color: #bbb;
color: #555;
}
/* Text fields' focus effect */
.login input[type="email"]:focus,
.login input[type="password"]:focus {
border-color: #888;
}
.login input[type="submit"] {
background: #28d;
border-color: transparent;
color: #fff;
cursor: pointer;
}
.login input[type="submit"]:hover {
background: #17c;
}
/* Buttons' focus effect */
.login input[type="submit"]:focus {
border-color: #05a;
}
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringSecurityReturn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringSecurityReturn</name>
<description>SpringSecurityReturn</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
CONTROLLER
package com.example.springsecurityreturn.controller;
import com.example.springsecurityreturn.entity.Person;
import com.example.springsecurityreturn.services.PersonService;
import com.example.springsecurityreturn.util.PersonValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
@Controller
@RequestMapping("/auth")
public class AuthController {
private final PersonValidator personValidator;
private final PersonService personService;
@Autowired
public AuthController(PersonValidator personValidator, PersonService personService) {
this.personValidator = personValidator;
this.personService = personService;
}
@GetMapping("/login")
public String loginPage(@ModelAttribute(name = "user") Person person) {
return "login";
}
@GetMapping("/registration")
public String registrationPage(@ModelAttribute("person") Person person) {
return "registration";
}
@PostMapping("/registration")
public String performRegistration(@ModelAttribute("person") @Valid Person person,
//an error is placed here
BindingResult bindingResult) {
personValidator.validate(person, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
personService.register(person);
return "redirect:/auth/login";
}
}
SECURITY CONFIGURATION
package com.example.springsecurityreturn.config;
import com.example.springsecurityreturn.services.PersonDetailsService;
import lombok.Builder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity //указывает на то, что конфигурационный класс SpringSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final PersonDetailsService personDetailsService;
private final String[] allowedPages = new String[] {
"/auth/login",
"/error",
"/auth/registration",
"/css/**"
};
@Autowired
public SecurityConfig(PersonDetailsService personDetailsService) {
this.personDetailsService = personDetailsService;
}
//настраивает логику аутентификации
//даем понять SpringSecurity что для аутентификации используется
//именно этот AuthProviderImpl
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(personDetailsService);//упрощение
}
//настройка формы для логина
@Override //переопределяется из WebSecurityConfigurerAdapter
protected void configure(HttpSecurity http) throws Exception {
//конфигурация страницы входа, выхода, ошибки и т.д.
//конфигурация авторизации (доступ по роли к страницам)
//работает с http
http
.csrf().disable() //че-то с токеном
.authorizeHttpRequests()
//страницы доступные всем
.antMatchers(allowedPages).permitAll()
//остальные запросы недоступны
.anyRequest().authenticated()
.and() //and - объединитель разных настроек, настройка авторизации
.formLogin()
.loginPage("/auth/login") //метод захода в систему\
//SpringSecurity ожидает что сюда придут логин и пароль
//SpringSecurity сам обрабатывает данные
.loginProcessingUrl("/process_login")
//что происходит при успешной аутентификации
//перенаправление на /hello, true - всегда
.defaultSuccessUrl("/hello", true)
//unsuccessful with key error (located in view (th) show message)
.failureForwardUrl("/auth/login?error");
}
@Bean //возвращается используемый алгоритм шифрования
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
[POSTMAN][1]
[PROJECT STRUCTURE][2]
[CSS HTTP][3]
[1]: https://i.stack.imgur.com/G8BKG.png
[2]: https://i.stack.imgur.com/IM9Ab.png
[3]: https://i.stack.imgur.com/kw7mE.png
</details>
# 答案1
**得分**: 0
你已经两次包含了 registration.css -- 移除这行代码 `<link rel="stylesheet" type="text/css" href="../static/css/registration.css">`,这是不正确的。
另外,允许未经身份验证的用户访问 /css 文件夹。
```java
http.authorizeRequests().antMatchers("/css/**").permitAll()
希望这能帮助你;
英文:
You have included registration.css twice -- remove this line <link rel="stylesheet" type="text/css" href="../static/css/registration.css">
, which is incorrect.
Also, allow access to /css folder for unautenhticated users.
http.authorizeRequests().antMatchers("/css/**").permitAll()
Hope this helps;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论