728x90

Entity에서 참조할 때 No Argument Constructor 의 경우에 참조가능한 범위가 있다. 특히 이 경우에 AccessLevel 을 Package 단계로 설정해두면 빨간맛을 뱉는데, 물론 Compile 자체에는 문제가 없을지라도 빨간맛을 보기 싫다면 변경하면 된다.

 

@AllArgsConstructor(access = AccessLevel.PUBLIC)
@NoArgsConstructor(access = AccessLevel.PACKAGE)
@Builder(toBuilder = true)
@Table(name = "batch_user_emails")

 

이걸

@NoArgsConstructor(access = AccessLevel.PUBLIC)

Public 단계로 바꿔주면 된다.

 

에러를 그대로 해석하면 되는 문제다.

 

아래는 다른 블로그에서 찾아온 기본 맛에 대한 글

@NoArgsConstructor

기본 사용법은 다음과 같습니다.

@NoArgsConstructor
public class BookWithLombok {

    private Long id;
    private String isbn;
    private String name;
    private String author;
}

자바로 표현하면 다음과 같습니다.

public class BookWithOutLombok {

    private Long id;
    private String isbn;
    private String name;
    private String author;

    public BookWithOutLombok() {

    }
}

@AllArgsConstructor

기본 사용법은 다음과 같습니다.

@AllArgsConstructor
public class BookWithLombok {

    private Long id;
    private String isbn;
    private String name;
    private String author;
    private boolean useYn;
}

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;
    private boolean useYn;

    public BookWithLombok(final Long id, final String isbn, final String name, final String author, final boolean useYn) {
        this.id = id;
        this.isbn = isbn;
        this.name = name;
        this.author = author;
        this.useYn = useYn;
    }
}

@RequiredArgsConstructor

기본 사용법은 다음과 같습니다.

@RequiredArgsConstructor
public class BookWithLombok {

    private final Long id;
    private final String isbn;
    private final String name;
    private final String author;
    private boolean useYn;
}

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private final Long id;
    private final String isbn;
    private final String name;
    private final String author;
    private boolean useYn;

    public BookWithLombok(final Long id, final String isbn, final String name, final String author) {
        this.id = id;
        this.isbn = isbn;
        this.name = name;
        this.author = author;
    }
}

 

 

access - 접근제한자

생성자의 대해서 접근제한자를 지정할 수 있습니다. 기본 접근제한자는 public 입니다.
접근제한자 목록은 다음과 같습니다.

PUBLIC

모든 곳에서 접근 가능합니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.PUBLIC)

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;

    public BookWithLombok() {
    }
}

MODULE

같은 패키지내에서 접근 가능합니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.MODULE)

자바로 표현하면 다음과 같습니다.
default 와 동일하며 같은 Lombok에서는 package 와 동일합니다.

public class BookWithLombok { 
    private Long id; 
    private String isbn; 
    private String name; 
    private String author; 

    BookWithLombok() { 
    } 
}

PROTECTED

같은 패키지 또는 자식 클래스에서 사용할 수 있습니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.PROCTECTED)

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;

    protected BookWithLombok() {
    }
}

PACKAGE

같은 패키지안에서 접근 가능하며 MODULE 과 동일한 기능을 합니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.PACKAGE)

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;

    BookWithLombok() {
    }
}

PRIVATE

내부 클래스에서만 사용할 수 있습니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.PRIVATE)

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;

    private BookWithLombok() {
    }
}

NONE

기본값인 PUBLIC 과 동일합니다.
다음과 같이 사용할 수 있습니다.

@NoArgsConstructor(access = AccessLevel.NONE)

자바로 표현하면 다음과 같습니다.

public class BookWithLombok {
    private Long id;
    private String isbn;
    private String name;
    private String author;

    public BookWithLombok() {
    }
}

출처: https://lovethefeel.tistory.com/71 [사는 이야기:티스토리]

728x90

 

 

말 그대로 import 구문을 빠트렸을 때 발생할 수 있는 상태이다. 일반적으로는 assertion 을 좀더 가독성을 늘리기 위해서 Hamcrest matcher 와 사용되곤 하는데 JUnit 에 들어있다. 

 

또한 Spring Boot test starter 에 의존성을 가진다

 

 

상단부에서 라이브러리를 납치해준다. IntelliJ 에서 import 하고 싶다고 마우스를 댓다간 못찾는 사태가 있다

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

 

 

 

JUnit 5(JUnit Jupiter)를 사용하는 경우에는 대게 JUnit 5의 Assertion 을 사용하고, 이 경우에는 직접적으로 assertThat method를 포함시키진 않는다.

 

하쥐만 Hamcrest matcher 를 import 구문을 상단에 포함시킴으로써 같이 사용할 수 있따.

 

예시

@Test
public void shouldLoginUserSuccessfully() throws Exception {
    // ... setup for mockMvc.perform ...

    MvcResult result = mockMvc.perform(/* your mockMvc perform call */).andReturn();
    String responseBody = result.getResponse().getContentAsString();

    // Use assertThat with a Hamcrest matcher
    assertThat(responseBody, containsString("expectedToken"));
}

 

 

취향껏 추가해보자

JUnit 5를 사용하고 native assertion library 사용에서 말뚝을 박고 싶은 경우에는 Assertion.assertTrue 를 String.contains 와 합쳐서 쓸 수 있다.

 

import org.junit.jupiter.api.Assertions;

// Inside your test method
Assertions.assertTrue(responseBody.contains("expectedToken"), "Response body does not contain expected token");
728x90
        // Generate JWT token
        return Jwts.builder()
                .setSubject(user.getUserId())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24 hours expiration
                .signWith(SignatureAlgorithm.HS512, "YourSecretKey") // Replace 'YourSecretKey' with your actual secret key
                .compact();

 

 

io.jsonwebtoken library 안에서 signWith (SignatureAlgorithm, String) 라는 놈은 이제 Deprecated 된 놈 중 하나인데 보안적인 이유때문에 짜진 친구이다.

 

이제는 String 대신에 Key 하나를 던져서 보안성을 강화해보자

 

 

Key 를 사용하기 위해 Library 2개를 더 납치해준다

import javax.crypto.SecretKey;
import io.jsonwebtoken.security.Keys;
@Service
public class AuthService {

    @Autowired
    private UserRepository userRepository;

    private final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS512); // Securely generate a key

    public String authenticateAndGenerateToken(LoginDto loginDto) {
        User user = userRepository.findByUserId(loginDto.getUserId());

        if (user == null || !new BCryptPasswordEncoder().matches(loginDto.getPassword(), user.getPassword())) {
            throw new IllegalArgumentException("Invalid credentials");
        }

        return Jwts.builder()
                .setSubject(user.getUserId())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24 hours expiration
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();
    }
}

 

 

728x90

기본적으로 조져지던 Swagger는 Springfox 에서 조져지는데 이 친구들은 3.x.x 대로 올라오면서 사실상 업데이트가 제대로 맞춰지지 않았기 때문에 엄청나게 거시기 한 점이 있다.

 

 따라서 OpenAPI의 SpringDoc 를 조져주는 게 좋은데,  이 경우에도 버전에 따라서 양상이 좀 다르게 바뀐다

 

3 버전대 이전 버전에서 Spring Doc 조지기

implementation("org.springdoc:springdoc-openapi-ui:1.6.11")

 

3.2.2 버전의 경우 아래와 같이 dedencies 를 조져준다

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

 

잘 보면 의존성에 따라서 Library 가 변한 것을 알 수 있는데, 결과적으로 버전에 따른 Library 를 안맞춰주면 

Whitelabel Error Page를 감상할 수 있다.

대충 이렇게 생긴 친구인데 의존성을 안맞춰주면 2024년도에도 이렇게 똑같이 발생한다는 말이다.

 

또한 괜히 Library 는 많으면 많을 수록 좋다는 생각으로 2가지 친구를 동시에 추가시켜 줬다가는 다음과 같은 빨간맛을 볼 수 있다.

 

after Using .apis(RequestHandlerSelectors.basePackage("com.szs.columbus.controller")) // Replace with your controller package, I'm in error like this
Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually:

 

그리고 추가적으로 종종 localhost 기반에서 들어가서 접속해보면 박스가 하나 뜨면서 

너새끼의 basePackage 가 잘못되었으니 수동으로 한번 꼬라박아줄래? 라고 계속 물어본다

 


번외. Springfox 너새끼는 어디까지 가능한가

추가적으로 Springfox 3.0.0에서는 Spring Boot 2.5와 2.6 에서 사용되는 것과 별개로 약간의 변화가 생기는데.

2. Remove Explicit @EnableSwagger2 Annotation

Springfox 3.0.0 and later versions with Spring Boot starters do not require the @EnableSwagger2 annotation. You can remove this annotation from your configuration class.

 

Annotation 하나를 제거해준다는 특징이 있다.

 

결론 = 그냥 어지간하면 이제는 OpenAPI 의 SpringDoc 이 답이다

 


추가적으로 application.properties 에서 path 기반하에 있는걸 다 박아주는 것도 설정할  수 있는데

 

In application.properties 

# Swagger Base
springdoc.packages-to-scan=com.szs.columbus.controller

 

이런식으로 Controller Package 하부를 죄다 박아버릴 수 있다. (이건 당연히 예전에 Springfox 에서도 지원되던 것이다.)

 

 

참조하면 좋은 글

https://sjh9708.tistory.com/169

 

[Spring Boot] Swagger API Docs 작성하기 (SpringDoc, SpringBoot 3 버전)

이전에 Spring Boot 프로젝트에 Swagger를 연동해 본 적이 있었다. 최근 Spring Boot의 지원 버전이 3점대로 올라감과 동시에, 2점대에서 Swagger 사용 목적으로 많이 사용되는 SpringFox가 안타깝게도 제대로

sjh9708.tistory.com

https://colabear754.tistory.com/99

 

[Spring Boot] Springdoc 라이브러리를 통한 Swagger 적용

목차 기본 환경 IntelliJ Ultimate 2022.3 Spring Boot 2.7.7 Kotlin 1.7.21(JDK 11) Springdoc Openapi UI 1.6.11 Springdoc은 무엇인가? 이전에 Spring Boot 프로젝트에 Swagger UI를 적용하는 포스트를 작성한 적이 있다. 해당 포

colabear754.tistory.com

 

+ Recent posts