QPAT commited on
Commit
fd9e00e
·
1 Parent(s): dcb04a2

Fix poerformance nd security

Browse files
pom.xml CHANGED
@@ -48,6 +48,15 @@
48
  <groupId>org.springframework.boot</groupId>
49
  <artifactId>spring-boot-starter-data-jpa</artifactId>
50
  </dependency>
 
 
 
 
 
 
 
 
 
51
  <dependency>
52
  <groupId>org.projectlombok</groupId>
53
  <artifactId>lombok</artifactId>
 
48
  <groupId>org.springframework.boot</groupId>
49
  <artifactId>spring-boot-starter-data-jpa</artifactId>
50
  </dependency>
51
+ <dependency>
52
+ <groupId>org.springframework.boot</groupId>
53
+ <artifactId>spring-boot-starter-cache</artifactId>
54
+ </dependency>
55
+ <dependency>
56
+ <groupId>com.github.ben-manes.caffeine</groupId>
57
+ <artifactId>caffeine</artifactId>
58
+ <version>3.1.8</version>
59
+ </dependency>
60
  <dependency>
61
  <groupId>org.projectlombok</groupId>
62
  <artifactId>lombok</artifactId>
src/main/java/com/darkfantasy/config/WebConfig.java CHANGED
@@ -1,6 +1,11 @@
1
  package com.darkfantasy.config;
2
 
 
 
 
 
3
  import org.springframework.context.annotation.Configuration;
 
4
  import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
5
  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
6
  import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -9,6 +14,8 @@ import com.darkfantasy.security.ForceChangePasswordInterceptor;
9
 
10
  import lombok.RequiredArgsConstructor;
11
 
 
 
12
  @Configuration
13
  @RequiredArgsConstructor
14
  public class WebConfig implements WebMvcConfigurer {
@@ -24,4 +31,20 @@ public class WebConfig implements WebMvcConfigurer {
24
  public void addInterceptors(InterceptorRegistry registry) {
25
  registry.addInterceptor(interceptor);
26
  }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  package com.darkfantasy.config;
2
 
3
+ import jakarta.servlet.FilterChain;
4
+ import jakarta.servlet.ServletException;
5
+ import jakarta.servlet.http.HttpServletRequest;
6
+ import jakarta.servlet.http.HttpServletResponse;
7
  import org.springframework.context.annotation.Configuration;
8
+ import org.springframework.web.filter.OncePerRequestFilter;
9
  import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
10
  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
11
  import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
14
 
15
  import lombok.RequiredArgsConstructor;
16
 
17
+ import java.io.IOException;
18
+
19
  @Configuration
20
  @RequiredArgsConstructor
21
  public class WebConfig implements WebMvcConfigurer {
 
31
  public void addInterceptors(InterceptorRegistry registry) {
32
  registry.addInterceptor(interceptor);
33
  }
34
+
35
+ @org.springframework.context.annotation.Bean
36
+ public OncePerRequestFilter pathTraversalFilter() {
37
+ return new OncePerRequestFilter() {
38
+ @Override
39
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
40
+ throws ServletException, IOException {
41
+ String path = request.getRequestURI();
42
+ if (path.contains("..") || path.contains("./")) {
43
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
44
+ return;
45
+ }
46
+ filterChain.doFilter(request, response);
47
+ }
48
+ };
49
+ }
50
+ }
src/main/java/com/darkfantasy/service/impl/ArticleServiceImpl.java CHANGED
@@ -2,6 +2,9 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.PageRequest;
7
  import org.springframework.data.domain.Pageable;
@@ -36,6 +39,7 @@ public class ArticleServiceImpl implements ArticleService {
36
  return ArticleResponse.fromEntity(findArticle(id));
37
  }
38
 
 
39
  @Transactional
40
  @Override
41
  public ArticleResponse createArticle(CreateArticleRequest request) {
@@ -54,6 +58,7 @@ public class ArticleServiceImpl implements ArticleService {
54
  return ArticleResponse.fromEntity(savedArticle);
55
  }
56
 
 
57
  @Transactional
58
  @Override
59
  public ArticleResponse updateArticle(UpdateArticleRequest request) {
@@ -85,6 +90,7 @@ public class ArticleServiceImpl implements ArticleService {
85
  return ArticleResponse.fromEntity(article);
86
  }
87
 
 
88
  @Transactional
89
  @Override
90
  public void deleteArticle(Long articleId) {
@@ -102,12 +108,14 @@ public class ArticleServiceImpl implements ArticleService {
102
  "Xóa bài viết: " + article.getTitle());
103
  }
104
 
 
105
  @Override
106
  public Page<ArticleResponse> getArticlesDeletedFalse(Pageable pageable) {
107
  return articleRepository.findByDeletedFalseOrderByCreatedAtDesc(pageable)
108
  .map(ArticleResponse::fromEntity);
109
  }
110
 
 
111
  @Override
112
  public List<ArticleResponse> getLatestArticles(int limit) {
113
 
@@ -119,6 +127,7 @@ public class ArticleServiceImpl implements ArticleService {
119
  .toList();
120
  }
121
 
 
122
  @Override
123
  public ArticleResponse getLatestImportantArticle() {
124
 
@@ -136,6 +145,7 @@ public class ArticleServiceImpl implements ArticleService {
136
  return articleRepository.findAll(pageable).map(ArticleResponse::fromEntity);
137
  }
138
 
 
139
  @Transactional
140
  @Override
141
  public void restoreArticle(Long articleId) {
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.CachePut;
7
+ import org.springframework.cache.annotation.Cacheable;
8
  import org.springframework.data.domain.Page;
9
  import org.springframework.data.domain.PageRequest;
10
  import org.springframework.data.domain.Pageable;
 
39
  return ArticleResponse.fromEntity(findArticle(id));
40
  }
41
 
42
+ @CacheEvict(value = "articles", allEntries = true)
43
  @Transactional
44
  @Override
45
  public ArticleResponse createArticle(CreateArticleRequest request) {
 
58
  return ArticleResponse.fromEntity(savedArticle);
59
  }
60
 
61
+ @CacheEvict(value = "articles", allEntries = true)
62
  @Transactional
63
  @Override
64
  public ArticleResponse updateArticle(UpdateArticleRequest request) {
 
90
  return ArticleResponse.fromEntity(article);
91
  }
92
 
93
+ @CacheEvict(value = "articles", allEntries = true)
94
  @Transactional
95
  @Override
96
  public void deleteArticle(Long articleId) {
 
108
  "Xóa bài viết: " + article.getTitle());
109
  }
110
 
111
+ @Cacheable(value = "articles", key = "#pageable.pageNumber + '_' + #pageable.pageSize")
112
  @Override
113
  public Page<ArticleResponse> getArticlesDeletedFalse(Pageable pageable) {
114
  return articleRepository.findByDeletedFalseOrderByCreatedAtDesc(pageable)
115
  .map(ArticleResponse::fromEntity);
116
  }
117
 
118
+ @Cacheable(value = "articles", key = "'latest_' + #limit")
119
  @Override
120
  public List<ArticleResponse> getLatestArticles(int limit) {
121
 
 
127
  .toList();
128
  }
129
 
130
+ @Cacheable(value = "articles", key = "'important'")
131
  @Override
132
  public ArticleResponse getLatestImportantArticle() {
133
 
 
145
  return articleRepository.findAll(pageable).map(ArticleResponse::fromEntity);
146
  }
147
 
148
+ @CacheEvict(value = "articles", allEntries = true)
149
  @Transactional
150
  @Override
151
  public void restoreArticle(Long articleId) {
src/main/java/com/darkfantasy/service/impl/ContributorServiceImpl.java CHANGED
@@ -2,6 +2,8 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.PageRequest;
7
  import org.springframework.data.domain.Pageable;
@@ -35,6 +37,7 @@ public class ContributorServiceImpl implements ContributorService {
35
  return ContributorResponse.fromEntity(findContributor(id));
36
  }
37
 
 
38
  @Transactional
39
  @Override
40
  public ContributorResponse createContributor(CreateContributorRequest request) {
@@ -53,6 +56,7 @@ public class ContributorServiceImpl implements ContributorService {
53
  return ContributorResponse.fromEntity(savedContributor);
54
  }
55
 
 
56
  @Transactional
57
  @Override
58
  public ContributorResponse updateContributor(UpdateContributorRequest request) {
@@ -84,6 +88,7 @@ public class ContributorServiceImpl implements ContributorService {
84
  return ContributorResponse.fromEntity(contributor);
85
  }
86
 
 
87
  @Transactional
88
  @Override
89
  public void deleteContributor(Long contributorId) {
@@ -101,6 +106,7 @@ public class ContributorServiceImpl implements ContributorService {
101
  "Xóa người đóng góp: " + contributor.getName());
102
  }
103
 
 
104
  @Override
105
  public Page<ContributorResponse> getContributorsDeletedFalse(Pageable pageable) {
106
  return contributorRepository.findByDeletedFalseOrderByPriorityDesc(pageable)
@@ -115,6 +121,7 @@ public class ContributorServiceImpl implements ContributorService {
115
  return contributorRepository.findAll(pageable).map(ContributorResponse::fromEntity);
116
  }
117
 
 
118
  @Transactional
119
  @Override
120
  public void restoreContributor(Long contributorId) {
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.Cacheable;
7
  import org.springframework.data.domain.Page;
8
  import org.springframework.data.domain.PageRequest;
9
  import org.springframework.data.domain.Pageable;
 
37
  return ContributorResponse.fromEntity(findContributor(id));
38
  }
39
 
40
+ @CacheEvict(value = "contributors", allEntries = true)
41
  @Transactional
42
  @Override
43
  public ContributorResponse createContributor(CreateContributorRequest request) {
 
56
  return ContributorResponse.fromEntity(savedContributor);
57
  }
58
 
59
+ @CacheEvict(value = "contributors", allEntries = true)
60
  @Transactional
61
  @Override
62
  public ContributorResponse updateContributor(UpdateContributorRequest request) {
 
88
  return ContributorResponse.fromEntity(contributor);
89
  }
90
 
91
+ @CacheEvict(value = "contributors", allEntries = true)
92
  @Transactional
93
  @Override
94
  public void deleteContributor(Long contributorId) {
 
106
  "Xóa người đóng góp: " + contributor.getName());
107
  }
108
 
109
+ @Cacheable(value = "contributors", key = "#pageable.pageNumber + '_' + #pageable.pageSize")
110
  @Override
111
  public Page<ContributorResponse> getContributorsDeletedFalse(Pageable pageable) {
112
  return contributorRepository.findByDeletedFalseOrderByPriorityDesc(pageable)
 
121
  return contributorRepository.findAll(pageable).map(ContributorResponse::fromEntity);
122
  }
123
 
124
+ @CacheEvict(value = "contributors", allEntries = true)
125
  @Transactional
126
  @Override
127
  public void restoreContributor(Long contributorId) {
src/main/java/com/darkfantasy/service/impl/FaqServiceImpl.java CHANGED
@@ -2,6 +2,8 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.Pageable;
7
  import org.springframework.stereotype.Service;
@@ -41,6 +43,7 @@ public class FaqServiceImpl implements FaqService {
41
  return FaqResponse.fromEntity(findFaq(id));
42
  }
43
 
 
44
  @Transactional
45
  @Override
46
  public FaqResponse createFaq(CreateFaqRequest request) {
@@ -60,6 +63,7 @@ public class FaqServiceImpl implements FaqService {
60
  return FaqResponse.fromEntity(faq);
61
  }
62
 
 
63
  @Transactional
64
  @Override
65
  public FaqResponse updateFaq(UpdateFaqRequest request) {
@@ -80,6 +84,7 @@ public class FaqServiceImpl implements FaqService {
80
  return FaqResponse.fromEntity(faq);
81
  }
82
 
 
83
  @Transactional
84
  @Override
85
  public void deleteFaq(Long id) {
@@ -96,6 +101,7 @@ public class FaqServiceImpl implements FaqService {
96
  "Xóa FAQ: " + found.getTitle());
97
  }
98
 
 
99
  @Transactional
100
  @Override
101
  public void restoreFaq(Long id) {
@@ -112,6 +118,7 @@ public class FaqServiceImpl implements FaqService {
112
  "Khôi phục FAQ: " + found.getTitle());
113
  }
114
 
 
115
  @Override
116
  public List<FaqResponse> getFaqsDeletedFalse() {
117
  return faqRepository
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.Cacheable;
7
  import org.springframework.data.domain.Page;
8
  import org.springframework.data.domain.Pageable;
9
  import org.springframework.stereotype.Service;
 
43
  return FaqResponse.fromEntity(findFaq(id));
44
  }
45
 
46
+ @CacheEvict(value = "faqs", allEntries = true)
47
  @Transactional
48
  @Override
49
  public FaqResponse createFaq(CreateFaqRequest request) {
 
63
  return FaqResponse.fromEntity(faq);
64
  }
65
 
66
+ @CacheEvict(value = "faqs", allEntries = true)
67
  @Transactional
68
  @Override
69
  public FaqResponse updateFaq(UpdateFaqRequest request) {
 
84
  return FaqResponse.fromEntity(faq);
85
  }
86
 
87
+ @CacheEvict(value = "faqs", allEntries = true)
88
  @Transactional
89
  @Override
90
  public void deleteFaq(Long id) {
 
101
  "Xóa FAQ: " + found.getTitle());
102
  }
103
 
104
+ @CacheEvict(value = "faqs", allEntries = true)
105
  @Transactional
106
  @Override
107
  public void restoreFaq(Long id) {
 
118
  "Khôi phục FAQ: " + found.getTitle());
119
  }
120
 
121
+ @Cacheable(value = "faqs", key = "'all'")
122
  @Override
123
  public List<FaqResponse> getFaqsDeletedFalse() {
124
  return faqRepository
src/main/java/com/darkfantasy/service/impl/GameCharacterServiceImpl.java CHANGED
@@ -2,6 +2,8 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.PageRequest;
7
  import org.springframework.data.domain.Pageable;
@@ -36,6 +38,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
36
  return GameCharacterResponse.fromEntity(findGameCharacter(id));
37
  }
38
 
 
39
  @Transactional
40
  @Override
41
  public GameCharacterResponse createGameCharacter(
@@ -59,6 +62,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
59
  savedCharacter);
60
  }
61
 
 
62
  @Transactional
63
  @Override
64
  public GameCharacterResponse updateGameCharacter(UpdateGameCharacterRequest request) {
@@ -85,6 +89,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
85
 
86
  }
87
 
 
88
  @Transactional
89
  @Override
90
  public void deleteCharacter(Long id) {
@@ -101,6 +106,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
101
  "Xóa nhân vật: " + found.getName());
102
  }
103
 
 
104
  @Transactional
105
  @Override
106
  public void restoreCharacter(Long id) {
@@ -124,6 +130,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
124
  .map(GameCharacterResponse::fromEntity);
125
  }
126
 
 
127
  @Override
128
  public List<GameCharacterResponse> getCharactersLimit(int limit) {
129
  if (limit <= 0)
@@ -134,6 +141,7 @@ public class GameCharacterServiceImpl implements GameCharacterService {
134
  .map(GameCharacterResponse::fromEntity).toList();
135
  }
136
 
 
137
  @Override
138
  public List<GameCharacterResponse> getCharactersDeletedFalse() {
139
  return gameCharacterRepository
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.Cacheable;
7
  import org.springframework.data.domain.Page;
8
  import org.springframework.data.domain.PageRequest;
9
  import org.springframework.data.domain.Pageable;
 
38
  return GameCharacterResponse.fromEntity(findGameCharacter(id));
39
  }
40
 
41
+ @CacheEvict(value = "characters", allEntries = true)
42
  @Transactional
43
  @Override
44
  public GameCharacterResponse createGameCharacter(
 
62
  savedCharacter);
63
  }
64
 
65
+ @CacheEvict(value = "characters", allEntries = true)
66
  @Transactional
67
  @Override
68
  public GameCharacterResponse updateGameCharacter(UpdateGameCharacterRequest request) {
 
89
 
90
  }
91
 
92
+ @CacheEvict(value = "characters", allEntries = true)
93
  @Transactional
94
  @Override
95
  public void deleteCharacter(Long id) {
 
106
  "Xóa nhân vật: " + found.getName());
107
  }
108
 
109
+ @CacheEvict(value = "characters", allEntries = true)
110
  @Transactional
111
  @Override
112
  public void restoreCharacter(Long id) {
 
130
  .map(GameCharacterResponse::fromEntity);
131
  }
132
 
133
+ @Cacheable(value = "characters", key = "'limit_' + #limit")
134
  @Override
135
  public List<GameCharacterResponse> getCharactersLimit(int limit) {
136
  if (limit <= 0)
 
141
  .map(GameCharacterResponse::fromEntity).toList();
142
  }
143
 
144
+ @Cacheable(value = "characters", key = "'all'")
145
  @Override
146
  public List<GameCharacterResponse> getCharactersDeletedFalse() {
147
  return gameCharacterRepository
src/main/java/com/darkfantasy/service/impl/StoryServiceImpl.java CHANGED
@@ -2,6 +2,8 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.Pageable;
7
  import org.springframework.stereotype.Service;
@@ -41,6 +43,7 @@ public class StoryServiceImpl implements StoryService {
41
  return StoryResponse.fromEntity(findStory(id));
42
  }
43
 
 
44
  @Transactional
45
  @Override
46
  public StoryResponse createStory(CreateStoryRequest request) {
@@ -62,6 +65,7 @@ public class StoryServiceImpl implements StoryService {
62
  return StoryResponse.fromEntity(savedStory);
63
  }
64
 
 
65
  @Transactional
66
  @Override
67
  public StoryResponse updateStory(UpdateStoryRequest request) {
@@ -88,6 +92,7 @@ public class StoryServiceImpl implements StoryService {
88
  return StoryResponse.fromEntity(story);
89
  }
90
 
 
91
  @Transactional
92
  @Override
93
  public void deleteStory(Long id) {
@@ -104,6 +109,7 @@ public class StoryServiceImpl implements StoryService {
104
  "Xóa câu chuyện: " + found.getTitle());
105
  }
106
 
 
107
  @Transactional
108
  @Override
109
  public void restoreStory(Long id) {
@@ -120,6 +126,7 @@ public class StoryServiceImpl implements StoryService {
120
  "Khôi phục câu chuyện: " + found.getTitle());
121
  }
122
 
 
123
  @Override
124
  public StoryResponse getStoryDeletedFalseHighestPriority() {
125
  Story story = storyRepository.findTopByDeletedFalseOrderByPriorityDesc();
@@ -129,6 +136,7 @@ public class StoryServiceImpl implements StoryService {
129
  return StoryResponse.fromEntity(story);
130
  }
131
 
 
132
  @Override
133
  public List<StoryResponse> getStoriesDeletedFalse() {
134
  return storyRepository
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.Cacheable;
7
  import org.springframework.data.domain.Page;
8
  import org.springframework.data.domain.Pageable;
9
  import org.springframework.stereotype.Service;
 
43
  return StoryResponse.fromEntity(findStory(id));
44
  }
45
 
46
+ @CacheEvict(value = "stories", allEntries = true)
47
  @Transactional
48
  @Override
49
  public StoryResponse createStory(CreateStoryRequest request) {
 
65
  return StoryResponse.fromEntity(savedStory);
66
  }
67
 
68
+ @CacheEvict(value = "stories", allEntries = true)
69
  @Transactional
70
  @Override
71
  public StoryResponse updateStory(UpdateStoryRequest request) {
 
92
  return StoryResponse.fromEntity(story);
93
  }
94
 
95
+ @CacheEvict(value = "stories", allEntries = true)
96
  @Transactional
97
  @Override
98
  public void deleteStory(Long id) {
 
109
  "Xóa câu chuyện: " + found.getTitle());
110
  }
111
 
112
+ @CacheEvict(value = "stories", allEntries = true)
113
  @Transactional
114
  @Override
115
  public void restoreStory(Long id) {
 
126
  "Khôi phục câu chuyện: " + found.getTitle());
127
  }
128
 
129
+ @Cacheable(value = "stories", key = "'highest_priority'")
130
  @Override
131
  public StoryResponse getStoryDeletedFalseHighestPriority() {
132
  Story story = storyRepository.findTopByDeletedFalseOrderByPriorityDesc();
 
136
  return StoryResponse.fromEntity(story);
137
  }
138
 
139
+ @Cacheable(value = "stories", key = "'all'")
140
  @Override
141
  public List<StoryResponse> getStoriesDeletedFalse() {
142
  return storyRepository
src/main/java/com/darkfantasy/service/impl/WorldServiceImpl.java CHANGED
@@ -2,6 +2,8 @@ package com.darkfantasy.service.impl;
2
 
3
  import java.util.List;
4
 
 
 
5
  import org.springframework.data.domain.Page;
6
  import org.springframework.data.domain.Pageable;
7
  import org.springframework.stereotype.Service;
@@ -42,6 +44,7 @@ public class WorldServiceImpl implements WorldService {
42
  return WorldResponse.fromEntity(findWorld(id));
43
  }
44
 
 
45
  @Transactional
46
  @Override
47
  public WorldResponse createWorld(CreateWorldRequest request) {
@@ -61,6 +64,7 @@ public class WorldServiceImpl implements WorldService {
61
  return WorldResponse.fromEntity(world);
62
  }
63
 
 
64
  @Transactional
65
  @Override
66
  public WorldResponse updateWorld(UpdateWorldRequest request) {
@@ -85,6 +89,7 @@ public class WorldServiceImpl implements WorldService {
85
  return WorldResponse.fromEntity(world);
86
  }
87
 
 
88
  @Transactional
89
  @Override
90
  public void deleteWorld(Long id) {
@@ -101,6 +106,7 @@ public class WorldServiceImpl implements WorldService {
101
  "Xóa thế giới: " + found.getTitle());
102
  }
103
 
 
104
  @Transactional
105
  @Override
106
  public void restoreWorld(Long id) {
@@ -117,6 +123,7 @@ public class WorldServiceImpl implements WorldService {
117
  "Khôi phục thế giới: " + found.getTitle());
118
  }
119
 
 
120
  @Override
121
  public WorldResponse getWorldDeletedFalseHighestPriority() {
122
  World world = worldRepository
@@ -129,6 +136,7 @@ public class WorldServiceImpl implements WorldService {
129
  return WorldResponse.fromEntity(world);
130
  }
131
 
 
132
  @Override
133
  public List<WorldResponse> getWorldsDeletedFalse() {
134
  return worldRepository
 
2
 
3
  import java.util.List;
4
 
5
+ import org.springframework.cache.annotation.CacheEvict;
6
+ import org.springframework.cache.annotation.Cacheable;
7
  import org.springframework.data.domain.Page;
8
  import org.springframework.data.domain.Pageable;
9
  import org.springframework.stereotype.Service;
 
44
  return WorldResponse.fromEntity(findWorld(id));
45
  }
46
 
47
+ @CacheEvict(value = "worlds", allEntries = true)
48
  @Transactional
49
  @Override
50
  public WorldResponse createWorld(CreateWorldRequest request) {
 
64
  return WorldResponse.fromEntity(world);
65
  }
66
 
67
+ @CacheEvict(value = "worlds", allEntries = true)
68
  @Transactional
69
  @Override
70
  public WorldResponse updateWorld(UpdateWorldRequest request) {
 
89
  return WorldResponse.fromEntity(world);
90
  }
91
 
92
+ @CacheEvict(value = "worlds", allEntries = true)
93
  @Transactional
94
  @Override
95
  public void deleteWorld(Long id) {
 
106
  "Xóa thế giới: " + found.getTitle());
107
  }
108
 
109
+ @CacheEvict(value = "worlds", allEntries = true)
110
  @Transactional
111
  @Override
112
  public void restoreWorld(Long id) {
 
123
  "Khôi phục thế giới: " + found.getTitle());
124
  }
125
 
126
+ @Cacheable(value = "worlds", key = "'highest_priority'")
127
  @Override
128
  public WorldResponse getWorldDeletedFalseHighestPriority() {
129
  World world = worldRepository
 
136
  return WorldResponse.fromEntity(world);
137
  }
138
 
139
+ @Cacheable(value = "worlds", key = "'all'")
140
  @Override
141
  public List<WorldResponse> getWorldsDeletedFalse() {
142
  return worldRepository
src/main/resources/application.properties CHANGED
@@ -46,4 +46,9 @@ spring.mail.properties.mail.smtp.starttls.enable=true
46
  server.error.include-message=never
47
  server.error.include-binding-errors=never
48
  server.error.include-stacktrace=never
49
- server.error.include-exception=false
 
 
 
 
 
 
46
  server.error.include-message=never
47
  server.error.include-binding-errors=never
48
  server.error.include-stacktrace=never
49
+ server.error.include-exception=false
50
+
51
+ # Cache Configuration
52
+ spring.cache.type=caffeine
53
+ spring.cache.caffeine.spec=maximumSize=500,expireAfterWrite=5m
54
+ spring.cache.cache-names=articles,characters,worlds,stories,faqs,contributors