토비의 스프링 3.1 책을 읽으며 일부분을 정리한 내용입니다. 
개념 이해를 위한 내용들 중 일부분을 정리했으므로 이해를 돕기위한 예시 코드들 및 자세한 전체적인 내용은 책을 통해 확인하시길 바랍니다.
포스팅 내용이 저작권의 문제가 발생할 경우 게시물은 바로 삭제/비공개 처리됩니다.

템플릿 

일정한 패턴으로 유지되는 특성을 가진 부분을 자유롭게 변경되는 성질을 가진 부분으로부터 독립시켜서 효과적으로 활용할 수 있도록 하는 방법

 

예외처리 기능을 갖춘  DAO

중간에 어떤 이유로든 예외가 발생했을 경우 사요하던 리소스를 무조건 반환하여 리소스 부족 문제를 막아야한다.

JDBC 코드에서는 try/catch/finally 구문을 활용해 리소스를 반환하도록 도와준다.

 

try/catch/finally 구문

try 구문

예외가 발생할 가능성이 있는 코드를 묶어준다.

catch 구문

예외가 발생했을 때 부가적인 작업을 해주도록 한다.

finally 구문

try 구문에서의 예외 발생 유무와 상관없이 항상 실행되는 구문이다. 

 

책에 나온 try/catch/finally 구문 사용하여 users 테이블을 다 지우는 예시 코드

public void deleteAll() throws SQLException {
		Connection c = null;
		PreparedStatement ps = null;
		try {
			c = dataSource.getConnection();
			ps = c.prepareStatement("delete from users");
			ps.execute();
		} catch (Exception e) {
			throw e;
		}finally {
			if(ps != null) {
				try {
					ps.close();
				}catch (SQLException e) {
				}
			}
			if (c != null) {
				try {
					c.close();
				} catch (SQLException e) {
				}
			}
		}
	}

close() 메소드 호출 시 오류 발생 시점에 따라 close() 함수 사용여부가 달라지므로 이를 주의해야한다.

 

 

 

토비의 스프링 3.1 책을 읽으며 일부분을 정리한 내용입니다. 
개념 이해를 위한 내용들 중 일부분을 정리했으므로 이해를 돕기위한 예시 코드들 및 자세한 전체적인 내용은 책을 통해 확인하시길 바랍니다.
포스팅 내용이 저작권의 문제가 발생할 경우 게시물은 바로 삭제/비공개 처리됩니다.

학습 테스트(learning test)

자신이 만들지 않은 프레임워크, 제공받은 라이브러리들에 대한 테스트

테스트를 만들려면 해당 기술, 기능에 대한 이해가 바탕이 돼야하므로 내가 제대로 이해하고 있는지 검증 가능

테스트 대상보다는 테스트 코드 자체에 관심을 가지고 만들어야하며 그 과정에서 사용법도 익힐 수 있다.

학습 테스트의 장점 4가지

1. 다양한 조건에 따른 기능을 손쉽게 확인해볼 수 있다.

자동화 : 눈으로 콘솔을 읽을 필요가 없이 성공/실패 여부를 알려줌

자동화된 테스트 코드 활용하기때문에 다양한 조건에 따라 기능이 어떻게 동작하는지 빠르게 확인 가능

2. 학습 테스트 코드를 개발 중에 참고할 수 있다.

테스트로 새로운 기술의 여러 기능들에 대한 사용 코드들을 작성해두면 실제 개발 착수시 샘플 코드로 활용 가능

3. 프레임워크나 제품을 업그레이드할 때 호환성 검증에 용이

적용을 하지 않고도 기존에 사용하던 API 기능에 문제가 없다는 사실을 미리 확인해볼 수 있는 방법

새로운 버전의 프레임워크나 제품을 학습 테스트에만 먼저 적용해봄

업그레이드시 버그가 발생하는지 미리 확인 가능해짐

4. 테스트 작성 좋은 훈련

 

버그 테스트(bug test)

코드에 오류가 있을 때 그 오류를 가장 잘 드러낼 수 잇는 테스트

일단 실패하도록 만든 후 코드를 수정하여 테스트가 성공하면 디버깅 완료

버그 테스트의 장점 3가지

1. 테스트의 완성도를 높여준다.

기존 테스트에서 미처 검증하지 못했던 부분 보완

2. 버그의 내용을 명확하게 분석하게 해준다.

테스트를 만들기 위해 분석하는 과정에서 버그를 좀 더 효과적으로 분석

동등 분할과 경계값 분석 적용해볼 수도

동등분할: 같은 결과 내는 각 범위의 대표 값으로 테스트 해보는 방법

경계값 분석: 동등분할 범위 경계 근처의 값들을 테스트하는 방법

3. 기술적인 문제를 해결하는 데 도움이 된다.

원인이 무엇인지 정확하게 파악하기 힘들 때 동일한 문제가 발생하는 가장 단순한 코드와

그에 대한 버그 테스트를 만들어 볼수도

외부의 도움을 요청할 때도 편함

 

스프링 부트로 프로젝트를 하면서 API를 만들어 포스트맨 확인 후 넘겨드렸는데 CORS 오류가 발생했다는 얘기를 전해들었다. 해당 오류는 SOP 정책을 위반했을 때 발생하는 오류이며 SOP 정책은 다음과 같다.

 

SOP(Same Origin Policy) 정책

같은 호스트, 같은 포트, 같은 프로토콜에서만 요청을 주고받을 수 있는 보안 정책

스프링 부트에서 아무런 설정을 적용하지 않으면 위 SOP 정책을 그대로 따르게 된다고 한다.

 

그럼 SOP 정책을 어떻게 변경할 수 있을까?

해답은 CORS(Cross-Origin Resource Sharing)을 이용하면 된다고 한다.

CORS는 같은 호스트, 같은 포트, 같은 프로토콜이 아니더라도 요청을 주고 받을 수 있도록 해준다.

 

CORS를 적용하는 법

1. CORS 적용이 필요한 컨트롤러 위에 @CrossOrigin("*") 애노테이션을 추가한다.

2. WebMvcConfigurer 인터페이스를 상속받아서 설정한다.(스프링 시큐리티 사용 안할 시)

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000");
    }

3. 스프링 시큐리티 설정 관련 config 파일에 아래 내용 추가 (스프링 시큐리티 사용할 시)

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.cors().configurationSource(request -> {
        var cors = new CorsConfiguration();
        //허용할 주소
        cors.setAllowedOrigins(List.of("http://localhost:3000")); 
        //허용할 http 메소드
        cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
        //허용할 header
        cors.setAllowedHeaders(List.of("*"));
        return cors;
    });

 

필자는 스프링 시큐리티를 사용하고 있어서 3번으로 해결했다.

 

참고 사이트

https://velog.io/@minchae75/Spring-boot-CORS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

 

 

Jwt 파싱할 때 발생한 오류다.

구글링해서 알아보니 parsing한 secert key 값이 원래 로컬에 저장된 secret key값과 달라서 발생하는 오류라고 한다.

 

먼저 오류 발생했던 초기 코드는 아래와 같다.

Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();

 

이후 구글링을 통해 다수의 사람들이 해결하던 .getBytes()를 추가하는 방식으로 수정해봤으나 오류가 해결되지 않았다.

.getBytes()를 통해 바이트 형식으로 키 값을 다뤄 key 값이 토큰에 들어가거나 파싱되는 순간에 변경이 되는 걸 방지한다는 디버깅 방식이었다.

Jwts.parser().setSigningKey(secretKey.getBytes()).parseClaimsJws(token).getBody().getSubject();

 

위 방식으로도 해결이 안된 이후로 몇 시간 동안 이 코드만 디버깅을 시도했었다.

구글링해도 자료가 많지 않아 난항을 겪고 있던 와중에 한 중국인이 올린 코드를 보게 됐고 그 분 방식처럼 아예 parsing하는 함수를 따로 분리하면서 문법도 바꿔 작성하니 오류가 해결됐다...

 

참고한 글은 아래 참고 사이트에 링크 남겼고 내가 작성한 오류 해결 코드는 아래와 같다.

 /**
     * Access 토큰 파싱
     * @param jwt
     * @return
     */
    public Claims parseJwt(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();

        return claims;
    }
    
    Claims claims = parseJwt(token);
    String s=claims.getSubject();

 

 

 

참고 사이트 

https://github.com/jwtk/jjwt/issues/177

EC2서버에서 스프링 부트 프로젝트를 돌리는데 계속 빌드를 하다 멈추는 일이 발생했다.

디스크 메모리 용량을 확인해보니 아직 한참 남아서 cpu 사용량을 확인해보니 RAM이 딸려서 발생하는 문제인 것 같았다.

알아보니 t2.micro의 램이 1GB밖에 안돼서 현재 서버에서 스프링 부트 빌드만 해도 터지는 것 같았다.

이전 스프링 부트 프로젝트를 할 때는 램이 모잘라서 터지진 않았는데

이번 스프링 부트 프로젝트는 사용하는 기술들이 많아 몸집이 상당히 커져서 계속 터지는 것 같다.

 

다행히 리눅스에서는 SWAP 메모리를 지정할 수 있어서 RAM이 부족할 때 HDD의 일정 공간을 마치 RAM처럼 사용할 수 있었다. 속도가 좀 느리긴 하지만 그래도 돌아가는게 어디인가

(실무에서는 좋은 해결 방법이 아닌 것 같은데 애초에 실무에서 쓰이는 서버라면 RAM이 1GB이지 않을 것 같다ㅎㅎ)

 

램이 2GB이하일 땐 보통 RAM 용량의 2배를 SWAP 메모리로 잡는데 ec2는 1GB로 SWAP 메모리는 2GB로 잡아서 설정할 예정이다. 이때 주의해야되는게 SWAP 메모리의 공간이 최소 32MB는 돼야한다고 한다.

 

free 명령어를 통해 메모리(램)과 SWAP 메모리를 확인해 볼 수 있다.

현재 이렇게 SWAP 메모리 할당이 안돼있는 상태이다.

이제 SWAP 메모리를 할당해보자.

sudo dd if=/dev/zero of=/swapfile bs=128M count=16   //2GB정도 공간 할당
sudo chmod 600 /swapfile    //swap 파일 권한 업데이트
sudo mkswap /swapfile    //linux swap 영역 설정
sudo swapon /swapfile    //swap space에 swap file 추가
sudo swapon -s    //위 명령어들 성공 확인

다음으로 /etc/fstab 파일을 편집하여 부팅 시 swap 파일을 활성화 해줘야 한다.

$ sudo vi /etc/fstab

제일 마지막에 아래 내용을 추가해준다.

/swapfile swap swap defaults 0 0

 

다시 free 명령어로 확인해보자.

 

참고사이트

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/
https://sundries-in-myidea.tistory.com/102

https://incomeplus.tistory.com/284?category=868671

ec2 서버에 프로젝트 코드를 정상적으로 옮기는 것 까지 성공했다면

이젠 해당 코드들을 빌드하고 무중단 서비스를 실행하고 중단해보자.

 

스프링 부트 프로젝트가 있는 이전 폴더로 이동합니다.

 

맨 처음 빌드시 permission denied가 뜨니 먼저 권한 설정부터 해줍니다.

chmod -R 777 프로젝트있는폴더명/

이후 프로젝트 폴더로 이동해줍니다.

 

스프링 부트 프로젝트 빌드 

./gradlew clean build

스프링 부트 무중단 서비스 시작

각자 맞는 실행파일 이름은 build/libs 폴더에 들어가서 확인할 수 있다.

nohup java -jar build/libs/{각자맞는이름}-0.0.1-SNAPSHOT.jar &

스프링 부트 무중단 서비스 종료

ps -ef | grep {각자맞는이름}-0.0.1-SNAPSHOT.jar
=>종료시킬 스프링 부트 pid 확인
sudo kill -9 확인한pid
=>무중단 스프링 부트 중지

+ Recent posts