Programming-[Backend]/SpringBoot 16

@SpringBootApplication 이해하기

1. @SpringBootApplication 소개 IntelliJ IDE에서 Spring Initializr를 통해 프로젝트를 새로 생성하면, 따로 Spring 관련 라이브러리들(ex. Spring Web 등)을 추가해주지 않더라도 java/main 메서드의 최상위 클래스 위에 @SpringBootApplication 어노테이션이 설정된다. 이 글에서는 해당 어노테이션의 기능에 대해서 정리해보고자 한다. 2. @SpringBootApplication의 기능 @SpringBootApplication은 Spring Bean 설정 기능과 라이브러리들의 의존성 추가 작업을 해준다. 즉 @EnableAutoConfiguration, @Configuration, @ComponentScan 어노테이션이 주 기능이라..

[탐험]Spring MVC, String 전체 앞 뒤 공백 제거하기! - MappingJackson2HttpMessageConverter, @JsonFormat, StringTrimmerEditor

1. 목표 SpringMVC를 이용하는 프로젝트에서 클라이언트의 입력값으로 들어오는 String 문자열 값의 앞 뒤 공백을 제거한다. "이름" : " 컴퓨터 탐험가 " -> "이름" : "컴퓨터 탐험가" 위와 같이 String의 앞 뒤 공백을 제거하는 것을 Java, Spring 쪽에서는 trim이라고 한다(자바스크립트에서도). 이 글의 목표는 프로젝트 전체에서 String값을 trimming하는 방법에 대해 정리하는 것이다. 개별 필드에 대한 trim에 대해서도 조금은 다룬다. 2. 방법과 적용 범위 집중적으로 다룰려고 하는 내용은 프로젝트 전체에서 trim을 적용하는 방법이다. 다만 이럴 경우 사용자가 의도적으로 문자열 앞뒤로 공백을 넣는 경우는 작동하지 않게될 수 있다. 예를 들어 비밀번호 입력 시..

[TIL][Spring security] hasRole 적용 시 access is denied 문제

문제 SecurityConfig에서 hasRole("MANAGER")로 권한을 주었는데도 "/messages" 페이지에 대한 접근이 불가했다. @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // .antMatchers("/mypage").hasRole("USER") .antMatchers("/messages").hasRole("MANAGER") // .antMatchers("/config").hasRole("ADMIN") .antMatchers("/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .logi..

[TIL][링크] MapStruct 라이브러리 - @AfterMapping

org.mapstruct 에서는 @AfterMapping 어노테이션을 지원한다. 해당 기능을 이용하면 데이터 전달 오브젝트인 DTO에서, 또는 DTO로 의 mapping이 일어난 후 어떤 메서드가 자동으로 실행되도록 할 수 있다. Mapper 클래스에서 @AfterMapping으로 mapping후 특정 메서드가 작동되도록 선언한다. 사용자로부터 입력받지 않은 값, 또는 서버에서 굳이 복잡한 로직을 거치지 않고 간단한 값을 클라이언트에 전달해주고 싶을 때 유용하게 사용할 수 있다. 예시코드 1 2 3 4 5 6 7 8 @Mapper(componentModel = "spring") public abstract class XxxPoToDtoMapper implements 제네릭으로 정의한 Mapper 인터페이..

[TIL][링크] messageSource application.yml 설정 옵션

지식 MessageSource와 관련된 설정들을 application.yml 파일에 작성할 수 있습니다. ( 참고 ) key 기본값 설명 spring.messages.always-use-message-format false MessasgeFormat을 전체 메시지에 적용할 것인지 여부 spring.messages.basename messages message 파일을 여러개 사용할 경우 콤마로 구분해서 여러개의 basename을 설정할 수 있다. spring.messages.cache-duration 캐시 주기 설정, 기본 값 forever spring.messages.encoding UTF-8 인코딩 방식 spring.messages.fallback-to-system-locale true 감지된 loca..

[TIL] Mapstruct - @Mapping 시 List의 필드값, the type of parameter has no property named

Mapstruct에서 @Mapping 사용 시 source와 target에서 필드값들을 매핑할 때, "the type of parameter has no property named" 에러가 나는 경우가 있다. 이것은 source와 target 경로 지정 시, Collection 타입이 아닌 부분을 조회하여 발생했을 수 있다. 이것은 마치 List 타입 내부의 size를 알 수 없는 객체들을 또 다른 size를 알 수 없는 List의 객체들로 매핑하는 것이 되기 때문이다. 요약하자면 아래 그림과 같다. 그럼 어떻게 해야할까? general 객체용 Mapper를 하나 만들어서 매핑하고, Soldier 객체용 Mapper를 만들어서 매핑을 반복적으로 수행한 뒤, 최종 general 객체로 합치면 된다. 정확한..

[링크][중요] Mapstruct 라이브러리, DTO와 Entity 검증의 주체가 되야하는 부분

1. Mapstruct 라이브러리 DTO 와 Entity간 변환을 쉽게 해주는 라이브러리다. [1] [보통 사용자의 입력값을 PO(Parameter Object)로 받아와서 DTO로 변환한다. 그리고 DTO의 값들을 Entity에 하나씩 넣어준 뒤 DB에서 Entity를 save 또는 update 하는 방식을 사용한다. 이 과정에서 DTO를 Entity로 바꿀 때, 또는 반대로 Entity를 기반으로 DTO로 바꿀 때 사용한다.] 필드값이 100개인 Entity의 100개 필드값을 DTO를 통해서 하나씩 전달해줄려면, Entity.setXxx(DTO.getXxx) 등으로 100개의 항목을 작성해줘야할 수도 있다. 그런데 Mapstruct의 @Mapper 방식을 사용하면 한줄만으로 이런 작업을 끝낼 수도 ..

[TIL][중요]Entity의 필드값 변경은 Service가 아닌 Entity에서 처리

Entity의 필드값 변경은 Service 코드 내에서가 아니라 Entity 코드 내에 작성하는 것이 좋다. 왜냐하면 어떤 Entity를 여러 서비스에서 사용할 수 있기 때문이다. 예를들어, 다음과 같은 1: N 연관관계를 갖는 엔티티가 있다고 가정하자. General 엔티티에 Soldier 엔티티가 1 : N으로 연결되어 있다. 서비스코드에서 파라미터로 받아온 dto의 값들을 general 엔티티 내부의 soldier 엔티티의 필드값으로 Set하는 addSoldiers 메서드는, 서비스 코드에서 작성하는 것이 아니라 Entity 코드에서 작성한다. 이렇게 하면 makeArmyServiceImpl 코드에서 뿐만 아니라, 다른 Service 코드에서도 addSoldiers 메서드를 활용할 수 있게 된다. ..

[TIL] Unique Id 아닌 값을 바탕으로 조회 및 update 할 때, findTopBy

다음 그림과 같이 Unique 값이 아닌 Id 값이 있는 경우가 있어서는 안되지만 있을 수도 있다. 그런데 만약 이 contact_id값을 바탕으로 객체를 불러와서 업데이트 하는 상황이라면, 일단 엔티티 객체를 조회할 때 contact_id에 해당하는 모든 엔티티 객체를 List 형태로 불러오고 List 내부의 모든 엔티티 객체의 값을 업데이트 하는 것이 바람직할 것이다. 상황에 따라 다르겠지만, 그렇게 해야 contact_id를 통해 값을 조회했을 때 일관성있는 결과값을 기대할 수 있게 된다. 차선의 방법으로, JPA에서의 findTop 메서드를 활용하여 쿼리 결과가 1개만 나오도록 해야 쿼리 결과상 문제가 발생하지 않는다. 쿼리 결과는 엔티티 객체 1개만 리턴하도록 지정해뒀는데, contact_id로..

[TIL] @JsonNaming 으로 Camel Case 필드값 Snake Case로 자동변환

@JsonNaming으로 클래스에 선언된 필드값들을 Camel Case로 작성하고 실제로 API를 통해 json 방식으로 데이터를 내보내거나, 받아올 때는 Snake Case로 자동으로 변환된다. 예를 들어 아래와 같이 companyId라고 작성된 필드는 외부와 API 통신을 하는 Swagger 문서에서는 company_id라고 표현된다. @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)