TIL(2023.10.16)

JAKE·2023년 10월 16일

TIL

목록 보기
42/48
post-thumbnail

🏃‍♂️What I learned

1. 필터(Filter)

  • 클라이언트의 요청 또는 응답을 걸러내거나 첨가하는 클래스

  • 필터 어노테이션 -> @Webfilter(filterName ="", urlPatterns = {""} )

    - filterName : 필터 별명
    - urlPatterns{" 요청 주소 "} : 요청 주소 안의 메서드가 필터에 걸림

  • filter의 구조 및 login filter 예시

@WebFilter(filterName = "loginFilter", urlPatterns = {"/myPage/*"}) 
public class LoginFilter implements Filter {

	public void init(FilterConfig fConfig) throws ServletException {
    /* 필터 초기화 메서드 : 서버 켜질 때, 필터 안의 코드가 변경되었을 때 */

	}
	
	public void destroy() { 
    /* 필터 파괴 메서드 : 필터 코드가 변경되었을 때 이전 코드 파괴*/
	
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
    throws IOException, ServletException { 

	/*  필터링 코드 작성*/

		/*1) ServlerRequest, ServletResponse 다운 캐스팅*/
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		
		
		/* 2) HttpServletRequest를 이용해서 HttpSession 얻어오기*/
		HttpSession session = req.getSession();
		
		
		/* 3) session에서 "loginMember" key를 가진 속성을 얻어와 
		      null인 경우 "/"로 리다이렉트*/
		if( session.getAttribute("loginMember") == null ) {
			
			resp.sendRedirect("/");
		
		} else {
		/* 4) 로그인 상태면 다음 필터 or dispatcherServlet으로 전달 */
			
			chain.doFilter(request, response);
			
		}	
	}
 }
 
 // "/myPage/*" : myPage 하위에 있는 주소들은 로그인되지 않으면 접근 불가

2. Spring에서 이미지 변경하기

  • JSP의 input = "file"
  • 파일 제출은 무조건 POST 방식
  • enctype : form 태그 데이터가 서버로 제출 될 때 인코딩 되는 방법 지정(post일때만 가능)
    1) application/x-www-form-urlencoded : 모든 문자를 서버로 전송하기 전에 인코딩
       (form태그 기본값)
    2) multipart/form-data : 모든 문자를 인코딩하지 않음
       (원본 데이터가 유지되어 이미지, 파일 등을 서버로 전송할 수 있음)
  • Controller에서 필요한 파라미터 불러오기
    @RequestParam("profileImage") MultipartFile profileImage,
    HttpSession session,
    @SessionAttribute("loginMember") Member loginMember,
    RedirectAttributes ra
  1. MultipartFile : input으로 올린 파일을 저장한 객체

    제공 메서드
    - transferTo() : 파일을 지정된 경로에 저장(메모리 -> HDD / SDD)
    - getOriginalFileName() : 파일 원본명
    - getSize() : 파일 크기

    1-1) MultipartFile 사용하기 위해서는 -> 모듈 추가 , bean 생성 필요
    1-2) 서버 설정 :
    서버 properties -> overview -> serve modules without publishing 체크

모듈 추가 -> pom.xml

<!-- 파일 업로드 관련 라이브러리 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.5</version>
</dependency>


bean 생성 -> root-context.xml

<!-- 
	파일 업로드를 위한 MutipartResolver 구현체 CommonsMultipartResolver bean 등록 

	-> CommonsMultipartResolver를 bean으로 등록하면 multipart/form-data 형식으로 요청 시 
	 input type="file" 태그를 자동적으로 인식하여 MultipartFile 객체로 반환하고 
	 파일 외의 데이터(정수, 문자열 등의 텍스트 데이터)는 기존처럼 사용 가능
     (MultipartRequest 필요 없음) 
	 
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="maxUploadSize" value="104857600"/>
	<property name="maxUploadSizePerFile" value="104857600"/>
	<property name="maxInMemorySize" value="104857600"/>
</bean>
	<!-- 
		104857600 byte == 100MB
		
		maxUploadSize 
			: 한 요청당 업로드가 허용되는 최대 용량을 바이트 단위로 설정.
			-1 은 제한이 없다는 뜻으로 이 프로퍼티를 지정하지 않을때 기본값.
		
		maxUploadSizePerFile
		 : 한 파일당 업로드가 허용되는 최대 용량을 바이트 단위로 설정.
			-1 은 제한이 없다는 뜻으로 이 프로퍼티를 지정하지 않을때 기본값.
			
		maxInMemorySize 
			: 디스크에 저장하지 않고 메모리 **(임시 저장 메모리)에 유지하도록 
			허용하는 바이트 단위의 최대 용량을 설정.
			
	 		사이즈가 이보다 클 경우 이 사이즈 이상의 데이터는 파일에 저장됩니다. 
			 기본값은 10240 바이트.
	 -->	
  • 웹 접근 경로 설정
String webPath = "/resources/images/member/"; 
// 실제로 이미지 파일이 저장되어야 하는 서버 컴퓨터 경로

String filePath = session.getServletContext().getRealPath(webPath); 
// servletContext -> 어플리케이션 스코프
  • 프로필 이미지 수정 서비스 호출
int result = service.updateProfile(profileImage, webPath, filePath, loginMember);
String msg = null;

if(result > 0) msg = "프로필 이미지가 변경되었습니다.";
else msg = "프로필 변경 실패";

ra.addFlashAttribute("msg", msg);

return "redirect:profile";
  • 프로필 이미지 수정 경우의 수
    1) 기존 x, 바꿈 o
    2) 기존 o, 바꿈 o
    3) 기존 o, 바꿈 x
public int updateProfile(MultipartFile profileImage, String webPath, String filePath, Member loginMember) throws Exception{
// 프로필 이미지 변경 실패 대비
	String temp = loginMember.getProfileImage(); // 기존 이미지 저장	
	String rename = null; // 변경할 이름 저장 변수		
		
	if(profileImage.getSize() > 0) { // 업로드 이미지가 있을 경우
			
		// 1) 업로드된 이미지의 이름 변경(util 클래스를 이용)
		rename = Util.fileRename(profileImage.getOriginalFilename());
			
		// 2) 바뀐 이름 loginMember에 세팅
		loginMember.setProfileImage(webPath + rename);

	} else { // 업로드된 이미지가 없는 경우(x버튼)
			
		loginMember.setProfileImage(null);
			
	}
		
	// 3) 프로필 이미지 수정 DAO 호출
	int result = dao.updateProfileImage(loginMember);
		
	if(result > 0) { // 업데이트 성공 시
			
		// 업로드된 새 이미지가 있을 경우
		if(rename != null) {
				
			//메모리에 임시 저장되어있는 파일을 서버에 진짜로 저장
			profileImage.transferTo( new File(filePath + rename));
				
		}
			
	} else { // 업데이트 실패 시
			
		// 이전 이미지로 프로필 다시 세팅
		loginMember.setProfileImage(temp);
			
	}
		
		return result;
}

0개의 댓글