파이널 프로젝트 Day-32 / 일일회고 Day-9

오늘 한 것

  • 회원 수정 기능에 이미지 교체 기능 추가
    :
    1. 회원가입 시 이미지 저장 실패 오류 -
      savefolder.properties 맥 경로 찾기
    2. member.controller에 savefoldername value 추가
    3. 404오류 - 경로오류(src주소 찾기)해결
    4. 비밀번호 암호화 오류 해결

디버깅 과정은

1. 회원가입 시 이미지 저장 실패 오류 -
savefolder.properties 맥 경로 찾기

회원수정을 위해 일단 회원가입을 먼저 하려고 했는데 (다른 팀원이 구현해놓은 회원가입 기능) 이미지 저장이 안돼 계속 가입에 실패했다. 왜 이미지 저장이 안될까 고민하다가 savefolder.properties를 열어보니 다른 팀원들은 모두 윈도우를 사용해 경로가 윈도우 주소로 작성되어 있었다.

나는 맥을 사용하므로 계속 c://upload/를 찾을 수 없어 이미지 저장이 실패한 것이다.

내 맥에 맞는 경로를 찾는 방법

파인더에 스프링 폴더를 찾고 그안에 upload 폴더를 찾았다.
그리고 마우스 우클릭으로 폴더 정보를 열어 i-cloud를 제외한 주소를 싹 복사해 savefoldername=에 붙여넣기 후 주소 끝에 /upload/까지 붙여주었다.

upload.path=는 그대로 /upload/** 를 썼는데,
이 문장은 servlet-context에서 업로드를 매핑할 때 쓰는 주소로 지정한 것이기 때문이다.

resource path는 파일을 가져오는 경로로 이해하고
savefoldername 주소와 동일하게 작성했다.

save path는 다른 이름으로 저장하는 경로로 이해하고
savefoldername 주소와 동일하게 작성했다.

이렇게 작성하니 회원가입은 실행이 되었고, upload폴더 안에
오늘 날짜로 폴더가 생성된 후 그 안에 이름이 바뀐 첨부파일이 저장됐다.

2. member.controller에 savefoldername value 추가

멤버 컨트롤러에서 내가 불러오고자 하는 파일을 요청하는 메소드를 작성하는데, 먼저 저장했던 폴더경로를 불러와야한다.
그러면 savefolder를 불러와야하므로

//	@Value("${savefoldername}")
//	private String saveFolder;

이 코드 말고

@Value("#{folder['savefoldername']}")
		private String saveFolder;

이 코드를 써서 날짜폴더가 아닌 한단계 상위 폴더 upload폴더를 찾아준다.

3. 404오류 - 경로오류(src주소 찾기)해결

2번이 왜 중요하냐면, 2번에서 날짜 폴더를 찾아주면 display 메소드의 경로가 잘못되기 때문이다.

display 메소드는 memberController에 작성한
savefolder안의 이미지를 보여주는 메소드인데

@GetMapping("/display")
	public ResponseEntity<byte[]> getImage(String fileName){
		File file = new File(saveFolder+ fileName);
		logger.info(fileName);
		ResponseEntity<byte[]> result = null;
		
		try {
			
			HttpHeaders header = new HttpHeaders();
			
			header.add("Content-type", Files.probeContentType(file.toPath()));
			
			result = new ResponseEntity<>(FileCopyUtils.copyToByteArray(file), header, HttpStatus.OK);
			
		}catch (IOException e) {
			e.printStackTrace();
		}
		
		return result;
	}

get메소드로 fileName을 통해 값을 가져온다.

File file = new File(saveFolder+ fileName);

file은 앞서 찾은 saveFolder값인 /upload 경로와
fileName은 컨트롤러에서 member값들을 넣어둔 member_info의 파일원래이름 member_info.original 값을 합쳐
경로를 완성한다.

그럼 이 경로는

http://
localhost:8088 (내 프젝의 로컬 호스트 주소)
/project (프로젝트 컨텍스트 주소?)
/member (멤버 컨트롤러 주소)
/display (display 메소드 주소)
?FileName= (받아올 Filename값 찾는 주소)
${member_info.original} (멤버인포에 저장한 오리지널 파일 주소 값)

-> http://localhost:8088/project/member/display?FileName=${member_info.original}

이 주소는 member_updateForm.jsp에서 프로필 이미지를
미리 보여주는 src 부분에 넣는다.

<b>프로필 사진</b>
			<label>
			<img src="../resources/image/chang/attach.png" width="25px">&nbsp;&nbsp;:&nbsp;&nbsp;
			<span id="showImage"><img width="25px" src ="/project/member/display?fileName=${member_info.original}"></span>
			<input type="file" name="uploadfile" accept="image/*">
			</label>

이렇게 작성하면 updateForm에서 이미 저장했었던 프로필 이미지와, 새로 불러올 이미지가 잘 보인다!

display 메소드와 이 경로를 이해하지 못해서 처음엔

src="${pageContext.request.contextPath}/resources/upload${member_info.original}"

라는 아주 이상한 주소를 썼고

그다음에는 팀원의 친절한 설명으로

src ="project/member/display?=fileName=${member_info.original}"

display 메소드주소와 member주소, project 주소를 깨닫고 썼지만 /를 앞에 안써서 그랬는지 project/member/project/member/display~하고 앞부분이 반복되었다.

앞에 /를 작성한 후에야 제대로 이미지가 보이고 수정이 잘 됐다.
경로가 어떻게 완성되는지 이해하는게 아주 중요한데, 팀원의 도움으로 하나씩 거꾸로 추적해보며 경로 작성 원리를 이해해서 기뻤다.

4. 비밀번호 암호화 오류 해결

이건 회원수정에서 비밀번호를 수정하지 않았는데도 불구하고
회원수정 버튼을 눌렀을 때 자동으로 비밀번호가 수정되어
그다음 로그인때 비밀번호 불일치 오류가 뜨는 상황을 해결하는 과정이다.

비밀번호 수정을 가능하게 하되, 비밀번호를 바꾸지 않았을때는
암호화된 비밀번호 정보를 그대로 유지 하게 해야했는데,

그렇게 하지 않을 경우 기존의 암호화된 비밀번호가 다시한번
암호화되어 다른 비밀번호로 바뀌기 때문이다.
그렇게 되는 원인은 memberController에서 작성한 updateProcess에 암호화 코드를 넣었기 때문이다.

@RequestMapping(value = "/updateProcess", method = RequestMethod.POST)
	  public String updateProcess( Member member, Model model,
			  					  HttpServletRequest request,
			
			  					  RedirectAttributes rattr)   {		  
		  
		  	String encPassword = passwordEncoder.encode(member.getPass());
			logger.info(encPassword);
			member.setPass(encPassword);
			
		  int result = memberService.update(member);
		  if (result == 1) {
			  rattr.addFlashAttribute("result", "updateSuccess");
			  return "redirect:/main";
		  } else {
			  model.addAttribute("url", request.getRequestURL());
			  model.addAttribute("message", "정보 수정 실패");
			  return "error/error";
		  }
	  }

String encPassword = passwordEncoder.encode(member.getPass());
logger.info(encPassword);
member.setPass(encPassword);

이 코드에서 이미 저장되어있는 비밀번호값을 member.getPass로 가져오면, 바꾸지 않아도 무조건 재암호화해서 다시 member.setPass로 바뀐 비밀번호를 저장하는 것이다.

무조건이 아니라 비밀번호를 바꿔입력했을때만 암호화를 시키기 위해
새로운 메소드를 작성했다.

 String OriginPass = memberService.OriginPass(member.getId(),member.getPass());
		  if(OriginPass == member.getPass()){
			  logger.info(OriginPass, member.getPass());
		  }else {
			  String encPassword = passwordEncoder.encode(member.getPass());
			  logger.info(encPassword);
			  member.setPass(encPassword);
		  }

원래 저장되어있던 비밀번호와, 새로 입력한 비밀번호의 일치여부에 따라 암호화 여부를 결정하는 메소드이다.

그런데 위의 코드는 제대로 실행되지 않았다.
그 이유는 새로 입력한 pass값을 제대로 가져오지 못했기 때문인 듯 하다.

제대로 pass값을 가져오는지 찾는과정은 내일 마저 하려 한다.

궁금한 것 & 어려운 것

메소드를 create하는 과정은 아직 낯설다.
dao와 xml도 아직 작성하지 않았는데, 왜 이부분은 작성을 안해도 스프링 상에서 오류 표시가 안나는지 궁금하다.

내일 할 것

제대로 pass값을 가져오게끔 메소드 수정하기
main에 여러 게시판 글 list 가져오기
footer 정리하기

모의 면접 준비..

좋은 웹페이지 즐겨찾기