Skip to content

Commit a69d35e

Browse files
feat: add logic for java-web-spring-boot-3 and update kotlin-web-spring-boot-3 (#99)
1 parent 45c3033 commit a69d35e

39 files changed

+1112
-27
lines changed

java-web-spring-boot-3/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ repositories {
1717

1818
dependencies {
1919
implementation 'org.springframework.boot:spring-boot-starter-web'
20+
implementation 'org.springframework.boot:spring-boot-starter-validation'
21+
implementation 'org.springframework.boot:spring-boot-starter-security'
22+
implementation 'org.springframework.boot:spring-boot-starter-actuator'
23+
runtimeOnly 'org.postgresql:postgresql:42.7.3'
24+
compileOnly 'org.projectlombok:lombok:1.18.32'
25+
annotationProcessor 'org.projectlombok:lombok:1.18.32'
2026
testImplementation 'org.springframework.boot:spring-boot-starter-test'
2127
}
2228

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.vndevteam.javawebspringboot3.application.demo;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.Size;
6+
import lombok.Getter;
7+
import lombok.Setter;
8+
9+
@Getter
10+
@Setter
11+
public class DemoReqDto {
12+
@NotBlank(message = "{email.not.blank}")
13+
@JsonProperty("email")
14+
private String email;
15+
16+
@Size(
17+
min = 5,
18+
max = 20,
19+
message = "The text1 '${validatedValue}' must be between {min} and {max} characters long"
20+
)
21+
@JsonProperty("text1")
22+
private String text1;
23+
24+
@Size(min = 5, max = 20, message = "{text2.length.between.min.max}")
25+
@JsonProperty("text2")
26+
private String text2;
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.vndevteam.javawebspringboot3.application.demo;
2+
3+
import com.vndevteam.javawebspringboot3.domain.enums.Message;
4+
import com.vndevteam.javawebspringboot3.infrastructure.util.MsgUtils;
5+
import jakarta.validation.Valid;
6+
import jakarta.validation.constraints.NotBlank;
7+
import org.springframework.context.i18n.LocaleContextHolder;
8+
import org.springframework.validation.annotation.Validated;
9+
import org.springframework.web.bind.annotation.*;
10+
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
14+
@Validated
15+
@RestController
16+
@RequestMapping("/demo")
17+
public class DemoRestController {
18+
@GetMapping("/locale-message")
19+
public Map<String, Object> getLocaleMessage() {
20+
Map<String, Object> map = new HashMap<>();
21+
map.put("request_locale", LocaleContextHolder.getLocale());
22+
map.put("msg", MsgUtils.getMessage(Message.MSG_1));
23+
return map;
24+
}
25+
26+
@PostMapping("/custom-validation-message")
27+
public String customValidationMessage(
28+
@RequestParam("name") @NotBlank(message = "{name.not.blank}") String name,
29+
@Valid @RequestBody DemoReqDto demoReq) {
30+
return name;
31+
}
32+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.vndevteam.javawebspringboot3.domain.enums;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum Message {
7+
MSG_1("msg-1"),
8+
MSG_2("msg-2"),
9+
ERR_1("err-1");
10+
11+
public final String code;
12+
13+
Message(String code) {
14+
this.code = code;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.vndevteam.javawebspringboot3.infrastructure.config;
2+
3+
import jakarta.annotation.PostConstruct;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.web.servlet.LocaleResolver;
8+
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
9+
10+
import java.util.Locale;
11+
import java.util.TimeZone;
12+
13+
@Configuration
14+
public class LocaleConfig {
15+
@Value("${app.locale.default}")
16+
private String defaultLocale;
17+
18+
@Value("${app.timezone.default}")
19+
private String defaultTimezone;
20+
21+
@PostConstruct
22+
void started() {
23+
TimeZone.setDefault(TimeZone.getTimeZone(defaultTimezone));
24+
}
25+
26+
/**
27+
* Default locale If the 'Accept-Language' header from request is present, and it is not empty,
28+
* we will use locale from it, otherwise — we’ll use default locale, which is ja.
29+
*/
30+
@Bean("localeResolver")
31+
public LocaleResolver acceptHeaderLocaleResolver() {
32+
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
33+
if (!defaultLocale.isBlank()) {
34+
localeResolver.setDefaultLocale(Locale.forLanguageTag(defaultLocale));
35+
}
36+
37+
return localeResolver;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.vndevteam.javawebspringboot3.infrastructure.config;
2+
3+
import com.vndevteam.javawebspringboot3.infrastructure.util.MsgUtils;
4+
import jakarta.annotation.PostConstruct;
5+
import org.springframework.context.MessageSource;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
9+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
10+
11+
@Configuration
12+
public class MessageConfig {
13+
public MessageSource messageSource() {
14+
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
15+
source.setBasename("message/messages");
16+
source.setDefaultEncoding("UTF-8");
17+
return source;
18+
}
19+
20+
@PostConstruct
21+
public void setMessageSource() {
22+
MsgUtils.setMessageSource(messageSource());
23+
}
24+
25+
/**
26+
* Register MessageSource bean with the LocalValidatorFactoryBean to use custom validation
27+
* message (get from messages.properties) Ex: @NotEmpty(message = "{name.not.empty}")
28+
*/
29+
@Bean
30+
public LocalValidatorFactoryBean validator() {
31+
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
32+
bean.setValidationMessageSource(messageSource());
33+
return bean;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.vndevteam.javawebspringboot3.infrastructure.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
8+
import org.springframework.security.web.SecurityFilterChain;
9+
10+
@Configuration
11+
@EnableWebSecurity
12+
public class SecurityConfig {
13+
@Bean
14+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
15+
http.authorizeHttpRequests(rq -> rq.anyRequest().permitAll())
16+
.csrf(AbstractHttpConfigurer::disable);
17+
18+
return http.build();
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.vndevteam.javawebspringboot3.infrastructure.config;
2+
3+
import com.vndevteam.javawebspringboot3.infrastructure.logging.MDCLoggingFilter;
4+
import lombok.Setter;
5+
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
10+
@Setter
11+
@Configuration
12+
@ConfigurationProperties(prefix = "app.slf4j-filter")
13+
public class Slf4jMDCFilterConfig {
14+
public static final String DEFAULT_RESPONSE_TOKEN_HEADER = "X-Client-Id";
15+
16+
private String responseHeader = DEFAULT_RESPONSE_TOKEN_HEADER;
17+
private String requestHeader;
18+
19+
@Bean
20+
public FilterRegistrationBean<MDCLoggingFilter> servletRegistrationBean() {
21+
FilterRegistrationBean<MDCLoggingFilter> registrationBean = new FilterRegistrationBean<>();
22+
System.out.println("Khuong test");
23+
System.out.println("responseHeader: " + responseHeader);
24+
System.out.println("requestHeader: " + requestHeader);
25+
MDCLoggingFilter log4jMDCFilterFilter =
26+
new MDCLoggingFilter(responseHeader, requestHeader);
27+
registrationBean.setFilter(log4jMDCFilterFilter);
28+
registrationBean.setOrder(2);
29+
return registrationBean;
30+
}
31+
}

0 commit comments

Comments
 (0)