7.회고 - well0924/coffie_place GitHub Wiki


1. vol.01 회고.

첫 프로젝트를 하면서 주제선정부터 프로젝트 배포까지의 전과정을 거치면서 전반적인 개발의 흐름을 알수 있는 기회였던 프로젝트였습니다. 전반적으로 스프링의 기본적인 기능 및 데이터베이스의 기본적인 쿼리를 적용하는 좋은 기회였습니다. 페이징 및 파일첨부 엑셀 다운기능을 공통모듈을 만들어서 적용을 해봤던 점과 스웨거를 사용해서 api의 자동 문서화 를 해봤던 점에서 의의를 두고 있습니다. 추가적으로 jpa공부를 하고 있는 중인데 진행이 어느정도 끝이나면 해당 프로젝트에도 mybatis가 아닌 jpa로 전환을 해볼 예정입니다.

1-1.개선점

  1. 스웨거를 적용을 했지만 특정 부분에서 응답을 달지 못한점(LocalDateTime부분)에서 찾아봐야겠다. (완료)

  2. 유효성 검사를 aop를 적용해서 유효성 처리를 해보기. (완료)

  3. 로그인을 폼로그인에서 jwt로그인으로 변경

  4. mybatis가 아닌 jpa로 변경하기.(완료)

  5. 배포를 젠킨슨(githubaciton)과 쿠버네티스를 사용해서 배포를 하기.

1-2. 느낀점

  • 1.개발 능력이 향상 되었다는 점.

    어찌보면 주니어 개발자입장에서는 당연한 입장이지 않을까 싶다. 계획 및 설계 부분에서도 많이 역량이 부족한 상태였지만

    프로젝트를 진행을 하면서 생기는 에러들을 해결해가면서 공부를 해가는 것도 많았었고, 각 기능을 구현하는데 필요한 로직을

    작성하는 방법과 데이터 베이스 쿼리작성 그리고 외부 api를 사용하면서 개발에 대한 숙련도를 익힐 수 있는 좋은 기회였다.

  • 2.외부 api를 써봤다는 점

    프로젝트를 진행을 하면서 프로젝트의 주제가 카페의 내용을 보여주기 위해서 kakao map을 활용을 하면서 가게조회에서 가게

    위,경도 값을 넣어서 지도에 보여준점 그리고 회원가입 및 회원수정부분에 daum post api를 사용해서 주소를 입력을 할 수 있었고,

    막상 외부 api를 사용하는데 있어서 불안감이 있었는데 외부 api를 사용하면서 한층 더 자신감을 가질 수 있는 기회였다.

  • 3.프로젝트 기간이 오래 걸린 점이다.

    물론 여러명이서 프로젝트를 하면 협업능력도 기를 수 있고 다른 사람과의 커뮤니케이션 능력도 기를 수 있는 좋은 기회일수 있겠지만

    여견상 개인 프로젝트로 진행을 했다는 점과 프로젝트를 하면서 특정 부분을 구현하는데 있어서 장기간의 시간이 걸렸다는 점과 개인적이

    사정으로 인해서 프로젝트가 길어졌다고 생각을 한다. 하지만 막상 프로젝트를 끝내고 난뒤 돌아보니 조금만 더 집중을 했다면 1달 이상은

    줄 일 수 있지 않았을까라는 생각이 들었다. 이런 점은 앞으로 개발자로서 안좋은 습관인것 같아 반성을 하는 계기로 삼아야겠다.

2. vol.01에서 개선했던점

  • 스웨거에서 일부 변수 어노테이션인식 해결

  • 해결: springfox-swagger2 라이브러리 안에 있는 swagger-annotations과 swagger-models의 버전충돌 문제로

         어노테이션과 모델의 라이브러리 버전을 1.5.21로 버전을 낮추는 방법과 스웨거 3.0으로 올리는 방법이 있다.
    
         에러문구 중에 java.lang.NumberFormatException: For input string: ""이 있는데 이 에러의 경우에는 
    
         스웨거 변수 설정에서 example로 정수를 지정하니깐 해결이 되었다.
    
         예) @ApiModelProperty(value="게시글번호",example="1")
      private Integer boardId;
    
  • aop를 활용을 해서 게시판 글작성,회원가입,가게등록 화면에 유효성검사를 하게끔했다.

  • 해결


@Log4j2
@Aspect
@Component
public class ValidatonHandler {
	
	@Around("execution(* com.kr.coffie.**..*ApiController.*(..))")
	public Object validationCheck(ProceedingJoinPoint joinpoint)throws Throwable{
		
	    String typeName = joinpoint.getSignature().getDeclaringTypeName();
	    String name = joinpoint.getSignature().getName();
	    Object[] args = joinpoint.getArgs();
		
		for(Object arg : args) {
			if(arg instanceof BindingResult) {
				BindingResult bindingResult = (BindingResult)arg;
				
				if(bindingResult.hasErrors()) {
					
					MaperrorMap = new HashMap<>();
					
					for(FieldError error : bindingResult.getFieldErrors()) {
						String validationkey = String.format("valid_%s", error.getField());
						
						log.info(typeName + "." + name + "() => 필드 : " + error.getField() + ", 메세지 : " + error.getDefaultMessage());
						
						errorMap.put(validationkey, error.getDefaultMessage());
					}
					
					return new ResponseDto<>(HttpStatus.BAD_REQUEST.value(),errorMap);
				}
			}
		}
		return joinpoint.proceed();
	}
}

@Around어노테이션을 선언하고 ApiController로 시작하는 컨트롤러에 있는 모든 메소드에 유효성 검사를 실행을 하도록했으며, 컨트롤러단에 있는 BindingResult를 선언을 해서 유효성 검사를 선언을 하게 되었다. 결과적으로 화면에서 자바스크립트로 했던 유효성 검사를 걷고 코드의 양을 전반적으로 줄일수가 있었다.

  • 컨트롤러에 있는 예외처리구문 대신에 전역적으로 예외처리를 하게끔 @RestControllerAdvice를 사용해서 코드를 리팩토링했다.

  • 해결


@RestControllerAdvice
public class GlobalExceptionHandler {

	@ExceptionHandler(value= Exception.class)
	public ResponseDto>IllegalArgumentException(Exception e)throws Exception{
		
		return new ResponseDto<>(HttpStatus.INTERNAL_SERVER_ERROR.value(),e.getMessage());
	}
	
}


@PostMapping(value="/write")
	public Maparticleinsert(
			@ApiParam(value="게시글 객체",required = true)
			@RequestBody
			@ModelAttribute BoardDto.BoardRequestDto dto,
			@ApiIgnore
			@ModelAttribute FileDto.FileRequestDto fvo)throws Exception{
		
		Mapresult = new HashMap();
		
		int insertresult = 0;

		try {

			fvo.setImgGroup("freeBoard");
			fvo.setFileType("Board");

			insertresult = service.boardwrite(dto, fvo);
			
			if(insertresult >0) {
				result.put("Common o.k", 200);
			
			}else if(insertresult < 0) {
			
				result.put("bad request", 400);
			
			}
		
		} catch (Exception e) {
			
			e.printStackTrace();
			
			result.put(e.getMessage(), 500);
		
		}
		
		return result;
	}

변경후


@PostMapping(value="/write")
	public ResponseDto>articleinsert(@Valid @ApiParam(value="게시글 객체",required = true) @RequestBody @ModelAttribute BoardDto.BoardRequestDto dto, 
			BindingResult bindingresult,
			@ApiIgnore @RequestBody @ModelAttribute FileDto.FileRequestDto fvo)throws Exception{
				
		int insertresult = 0;
		
		fvo.setImgGroup("freeBoard");
		fvo.setFileType("Board");
		
		insertresult = service.boardwrite(dto, fvo);
				
		return new ResponseDto<>(HttpStatus.OK.value(),200);
	}


⚠️ **GitHub.com Fallback** ⚠️