update springboot

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-06 18:18:28 +08:00
parent 388a34837f
commit e24b41f53c
7 changed files with 49 additions and 18 deletions
+2 -2
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version> <version>3.5.13</version>
<relativePath/> <relativePath/>
</parent> </parent>
<groupId>com.yaoyuan</groupId> <groupId>com.yaoyuan</groupId>
@@ -73,7 +73,7 @@
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version> <version>2.8.9</version>
</dependency> </dependency>
<!-- Lombok --> <!-- Lombok -->
@@ -12,7 +12,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@@ -52,17 +51,6 @@ public class WebSecurityConfig {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }
/**
* Exclude truly static assets from the security filter chain entirely.
* H2 console and Druid monitoring are NOT excluded here — they are secured via filterChain.
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring().requestMatchers(
"/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico"
);
}
/** /**
* Main security filter chain. * Main security filter chain.
* *
@@ -98,6 +86,7 @@ public class WebSecurityConfig {
http.authorizeHttpRequests(auth -> { http.authorizeHttpRequests(auth -> {
// Publicly accessible // Publicly accessible
auth.requestMatchers( auth.requestMatchers(
"/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico",
"/login/**", "/register", "/registerDo", "/initUserData", "/login/**", "/register", "/registerDo", "/initUserData",
"/", "/main", "/index", "/getdiscussionsbyid", "/", "/main", "/index", "/getdiscussionsbyid",
// SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data) // SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data)
@@ -21,13 +21,17 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author yaoyuan2.chu * @author yaoyuan2.chu
@@ -142,6 +146,19 @@ public class UserSystemController extends BaseController {
tagMap.put(tc.getDiscussionId(), tagCustomListTemp); tagMap.put(tc.getDiscussionId(), tagCustomListTemp);
} }
} }
Set<Integer> userIds = new HashSet<>();
for (Discussion dd : allDiscussions) {
if (dd.getStartUserId() != null) {
userIds.add(dd.getStartUserId());
}
if (dd.getLastUserId() != null) {
userIds.add(dd.getLastUserId());
}
}
Map<Integer, User> userMap = usersService.findAllById(userIds).stream()
.collect(Collectors.toMap(User::getId, u -> u));
for (Discussion dd : allDiscussions) { for (Discussion dd : allDiscussions) {
DiscussionCustom newdd = new DiscussionCustom(); DiscussionCustom newdd = new DiscussionCustom();
BeanUtils.copyProperties(dd, newdd); BeanUtils.copyProperties(dd, newdd);
@@ -154,13 +171,13 @@ public class UserSystemController extends BaseController {
} }
newdd.setContent(newCon); newdd.setContent(newCon);
if (null != newdd.getStartUserId()) { if (null != newdd.getStartUserId()) {
User startUser = usersService.findOne(newdd.getStartUserId()); User startUser = userMap.get(newdd.getStartUserId());
newdd.setAvatar(startUser != null && startUser.getAvatar() != null ? startUser.getAvatar() : ""); newdd.setAvatar(startUser != null && startUser.getAvatar() != null ? startUser.getAvatar() : "");
newdd.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : ""); newdd.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : "");
newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : ""); newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : "");
} }
if (null != newdd.getLastUserId()) { if (null != newdd.getLastUserId()) {
User lastUser = usersService.findOne(newdd.getLastUserId()); User lastUser = userMap.get(newdd.getLastUserId());
newdd.setAvatarLast(lastUser != null && lastUser.getAvatar() != null ? lastUser.getAvatar() : ""); newdd.setAvatarLast(lastUser != null && lastUser.getAvatar() != null ? lastUser.getAvatar() : "");
newdd.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : ""); newdd.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : "");
newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : ""); newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : "");
@@ -209,6 +226,11 @@ public class UserSystemController extends BaseController {
return "login"; return "login";
} }
@GetMapping("/favicon.ico")
public RedirectView favicon() {
return new RedirectView("/static/assets/images/logo.png");
}
/** /**
* 注册提交 * 注册提交
@@ -11,6 +11,8 @@ import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -69,6 +71,15 @@ public class GlobalExceptionHandler {
.body(ApiResponse.error("没有权限访问该资源")); .body(ApiResponse.error("没有权限访问该资源"));
} }
/** 404 mappings/resources should not be logged as system errors. */
@ExceptionHandler({NoHandlerFoundException.class, NoResourceFoundException.class})
public ResponseEntity<ApiResponse<Void>> handleNotFound(Exception ex) {
log.warn("Not found: {}", ex.getMessage());
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(ApiResponse.error("资源不存在"));
}
/** Catch-all for any unhandled exception — never expose stack traces to clients. */ /** Catch-all for any unhandled exception — never expose stack traces to clients. */
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<Void>> handleGeneral(Exception ex) { public ResponseEntity<ApiResponse<Void>> handleGeneral(Exception ex) {
@@ -24,5 +24,7 @@ public interface IUsersService {
User getByUsername(String username); User getByUsername(String username);
List<User> findAllById(Iterable<Integer> ids);
User update(User user, Integer id); User update(User user, Integer id);
} }
@@ -71,7 +71,7 @@ public class UsersServiceImpl implements IUsersService {
@Cacheable(value = "user", key = "#id") @Cacheable(value = "user", key = "#id")
@Override @Override
public User findOne(Integer id) { public User findOne(Integer id) {
return usersRepository.getById(id); return usersRepository.findById(id).orElse(null);
} }
/** /**
@@ -140,6 +140,12 @@ public class UsersServiceImpl implements IUsersService {
return usersRepository.getByUsername(username); return usersRepository.getByUsername(username);
} }
@Transactional(readOnly = true)
@Override
public List<User> findAllById(Iterable<Integer> ids) {
return usersRepository.findAllById(ids);
}
} }
@@ -1,4 +1,5 @@
<#--jquery--> <#--jquery-->
<link rel="icon" type="image/png" href="/static/assets/images/logo.png">
<script crossorigin="anonymous" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh" <script crossorigin="anonymous" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"></script> src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"></script>