diff --git a/pom.xml b/pom.xml
index f3e2286..f923361 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.3.5
+ 3.5.13
com.yaoyuan
@@ -73,7 +73,7 @@
org.springdoc
springdoc-openapi-starter-webmvc-ui
- 2.6.0
+ 2.8.9
diff --git a/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java b/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java
index 7451b47..e64581f 100644
--- a/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java
+++ b/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java
@@ -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.web.builders.HttpSecurity;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@@ -52,17 +51,6 @@ public class WebSecurityConfig {
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.
*
@@ -98,7 +86,8 @@ public class WebSecurityConfig {
http.authorizeHttpRequests(auth -> {
// Publicly accessible
auth.requestMatchers(
- "/login/**", "/register", "/registerDo", "/initUserData",
+ "/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico",
+ "/login/**", "/register", "/registerDo", "/initUserData",
"/", "/main", "/index", "/getdiscussionsbyid",
// SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data)
"/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**"
diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
index 243c277..abfdf34 100644
--- a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
+++ b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
@@ -21,13 +21,17 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.view.RedirectView;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author yaoyuan2.chu
@@ -142,6 +146,19 @@ public class UserSystemController extends BaseController {
tagMap.put(tc.getDiscussionId(), tagCustomListTemp);
}
}
+
+ Set userIds = new HashSet<>();
+ for (Discussion dd : allDiscussions) {
+ if (dd.getStartUserId() != null) {
+ userIds.add(dd.getStartUserId());
+ }
+ if (dd.getLastUserId() != null) {
+ userIds.add(dd.getLastUserId());
+ }
+ }
+ Map userMap = usersService.findAllById(userIds).stream()
+ .collect(Collectors.toMap(User::getId, u -> u));
+
for (Discussion dd : allDiscussions) {
DiscussionCustom newdd = new DiscussionCustom();
BeanUtils.copyProperties(dd, newdd);
@@ -154,13 +171,13 @@ public class UserSystemController extends BaseController {
}
newdd.setContent(newCon);
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.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : "");
newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : "");
}
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.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : "");
newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : "");
@@ -209,6 +226,11 @@ public class UserSystemController extends BaseController {
return "login";
}
+ @GetMapping("/favicon.ico")
+ public RedirectView favicon() {
+ return new RedirectView("/static/assets/images/logo.png");
+ }
+
/**
* 注册提交
diff --git a/src/main/java/com/yaoyuan/jiscuss/exception/GlobalExceptionHandler.java b/src/main/java/com/yaoyuan/jiscuss/exception/GlobalExceptionHandler.java
index 601bc36..8b42342 100644
--- a/src/main/java/com/yaoyuan/jiscuss/exception/GlobalExceptionHandler.java
+++ b/src/main/java/com/yaoyuan/jiscuss/exception/GlobalExceptionHandler.java
@@ -11,6 +11,8 @@ import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
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;
@@ -69,6 +71,15 @@ public class GlobalExceptionHandler {
.body(ApiResponse.error("没有权限访问该资源"));
}
+ /** 404 mappings/resources should not be logged as system errors. */
+ @ExceptionHandler({NoHandlerFoundException.class, NoResourceFoundException.class})
+ public ResponseEntity> 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. */
@ExceptionHandler(Exception.class)
public ResponseEntity> handleGeneral(Exception ex) {
diff --git a/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java b/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java
index 0933e16..f4708e8 100644
--- a/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java
+++ b/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java
@@ -24,5 +24,7 @@ public interface IUsersService {
User getByUsername(String username);
+ List findAllById(Iterable ids);
+
User update(User user, Integer id);
}
diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java
index 08fe990..132761c 100644
--- a/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java
+++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java
@@ -71,7 +71,7 @@ public class UsersServiceImpl implements IUsersService {
@Cacheable(value = "user", key = "#id")
@Override
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);
}
+ @Transactional(readOnly = true)
+ @Override
+ public List findAllById(Iterable ids) {
+ return usersRepository.findAllById(ids);
+ }
+
}
diff --git a/src/main/resources/templates/comm/commjs.ftl b/src/main/resources/templates/comm/commjs.ftl
index 0dff638..3751591 100644
--- a/src/main/resources/templates/comm/commjs.ftl
+++ b/src/main/resources/templates/comm/commjs.ftl
@@ -1,4 +1,5 @@
<#--jquery-->
+