글쓰기,파일업로드 기능 구현

·2024년 11월 7일

스프링

목록 보기
15/33

이클립스에서 boardWrite.jsp 파일을 스프링에 그대로 가져온다.

	@RequestMapping(value= "boardWrite.aws")
	public String boardWrite() {
		
		String path = "WEB-INF/board/boardWrite";
		return path;
	}

1. BoardController에서 화면만 띄울 수 있도록 일단 메소드 형식만 만들어두기.

2. 로그인을 해야만 글을 쓸 수 있기 때문에 config 패키지에 있는 servlet.xml 파일에 인터셉트를 추가해주면 된다. 이렇게 하면 글쓰기를 할 때 로그인 인증을 해야한다.


3. 글쓰기는 String뿐만 아니라 파일도 넘겨야 하기 때문에 binary타입으로 넘겨줘야 한다.
servlet-context.xml에 이미지도 넘길 수 있도록 멀티파트 리졸버도 설정을 해줘야 한다.

4. 경로를 지정했기 때문에 d드라이브 안에 dev안에 이름을 똑같이 스프링업로드라고 파일을 만들어준다. 여기에 업로드된 이미지들이 생길 예정.

@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction() {
		
		
		
	String path = "redirect:/board/boardList.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		return path;
	}
	

5. 다시 컨트롤러로 이동해서 action으로 메서드를 하나 더 만들어준다.

	@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction(BoardVo bv) {
		
		
		
	String path = "redirect:/board/boardList.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		return path;
	}

6. 바인딩해서 받기 (BoardVo bv)

@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction(
			BoardVo bv,
			@RequestParam("filename") MultipartFile filename
			) {
		
		
		
		String path = "redirect:/board/boardList.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		return path;
	}
	

7 파일타입을 따로 설정을 해줘야한다,

@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction(
			BoardVo bv,
			@RequestParam("filename") MultipartFile filename,
			HttpSession session
			) {
		
		
		
		String path = "redirect:/board/boardList.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		return path;
	}

8. 글쓸 때 회원 번호도 넘겨줘야 하니까 회원번호도 넘길수 있는 세션도 같이 넘긴다.

9. myapp에 util패키지 생성해서 파일 두 개 넣어두기. 파일을 생성시켜줄 수 있는 클래스들이다.
UploadFileUtiles 클래스는 파일을 업로드하고 관리하는 기능을 담당하는 유틸리티 클래스로, 이미지 파일을 서버에 업로드하면서 썸네일을 생성하거나 날짜별 폴더를 만들어 파일을 정리하는 등의 작업을 수행한다.

<!-- 파일업로드 -->
		<dependency>
		<groupId>org.imgscalr</groupId>
		<artifactId>imgscalr-lib</artifactId>
		<version>4.2</version>
		</dependency>
		
		<dependency>
		<groupId>commons-fileupload</groupId>
		<artifactId>commons-fileupload</artifactId>
		<version>1.3.2</version>
		</dependency>   

10. pom.xml에 가서 파일업로드에 필요한 라이브러리를 다운 받아야한다.

11. 다시 컨트롤러로 돌아와서 상단에 빈에 등록한 uploadPath를 주입해주기

//게시판에서 글 작성과 파일 업로드 기능을 처리
	@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction(
		BoardVo bv, // 게시글 정보를 담고 있는 BoardVo 객체를 매개변수로 받음
		@RequestParam("filename") MultipartFile filename, // 업로드된 파일을 받기 위한 MultipartFile 객체
		HttpSession session
		) throws Exception { // 윗단에 보고를 하는것
		MultipartFile file = filename; //저장된 파일 이름 꺼내기 
		String uploadedFileName=""; // 파일이 업로드된 후 저장된 파일명을 저장할 변수
		
		if(! file.getOriginalFilename().equals("")) { // 해당 파일이 존재한다면
			 // 파일을 서버에 저장하고 저장된 파일 이름을 반환받음
			uploadedFileName = UploadFileUtiles.uploadFile(uploadPath, file.getOriginalFilename(), file.getBytes());
		}
		
		
		  // 게시글 목록 페이지로 리다이렉트
		String path = "redirect:/board/boardList.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		return path;
	}
	

12. 적어주는데 빨간줄이 뜬다면 throws로 처리해주기. 여기서 처리하는게 아니라 나를 호출해준 윗단에서 처리를 해줘라. bv에 추가적으로 uploadedFilename을 추가적으로 넣어줘야 한다.

13. Boardvo에 담아야하니까 새로 만들어주기

// 서버 ip 추출하는 메소드 
		public String getUserIp(HttpServletRequest request) throws Exception {
			
	        String ip = null;
	      //  HttpServletRequest request = 
	      // ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();

	        ip = request.getHeader("X-Forwarded-For");
	        
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("Proxy-Client-IP"); 
	        } 
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("WL-Proxy-Client-IP"); 
	        } 
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("HTTP_CLIENT_IP"); 
	        } 
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
	        }
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("X-Real-IP"); 
	        }
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("X-RealIP"); 
	        }
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getHeader("REMOTE_ADDR");
	        }
	        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	            ip = request.getRemoteAddr(); 
	        }
	        
	        
	        if(ip.equals("0:0:0:0:0:0:0:1") || ip.equals("127.0.0.1")) {
	        	InetAddress address = InetAddress.getLocalHost();
	        	ip = address.getHostAddress();
	        }
			return ip;
		}

14. ip도 담아야하기 때문에 컨트롤러 아래에 ip매서드를 이클립스에서 가져온다.

15. Action메서드로 돌아와서 bv에 값 담아주기 그리고 세션 수정

public int boardInsert(BoardVo bv);

16. BoardService로 이동해서 boardInsert메서드 만들기. 새로운 게시글을 추가하고 그 게시글의 originbidx 값을 설정하는 메서드 이름.

	@Override
	public int boardInsert(BoardVo bv) {
		
	
		return 0;
	}

17. impl로 와서 구현되지 않은 메서드 add로 추가해준다.

public int boardInsert(BoardVo bv);
18. BoardMapper로 가서 마이바티스용 메서드도 똑같이 만들어주기

	@Override
	public int boardInsert(BoardVo bv) {
		
		int value = bm.boardInsert(bv);
		
	
		return 0;
	}

19. 다시 impl로 돌아와서 마이바티스 메서드를 불러온다.

<insert id="boardInsert" parameterType="bv">
insert into board(originbidx,depth,level_,subject,contents,writer,password,midx,filename,ip)
value(null,0,0,#{subject},#{contents},#{writer},#{password},#{midx},#{uploadedFilename},#{ip})
</insert>

20. boardMapper.xml로 가서 쿼리구문 만들어주기

<insert id="boardInsert" parameterType="bv">
<selectKey keyProperty="bidx" resultType="int" order="AFTER"> <!-- insert를 실행시키고 나서 selectkey를 실행해라  -->
select max(bidx) as bidx from board 
</selectKey>
insert into board(originbidx,depth,level_,subject,contents,writer,password,midx,filename,ip)
value(null,0,0,#{subject},#{contents},#{writer},#{password},#{midx},#{uploadedFilename},#{ip})
</insert>

21. insert를 하고 selectKey를 나중에 실행하는 구문 완성

22. impl로 가서 bidx값도 꺼내오면 된다.

public int boardOriginbidxUpdate(int bidx);
23. BoardMapper로 가서 보드에 bidx를 업데이트 치겠다, 라는 메서드 먼저 만들기

24. impl로 가서 업데이트 메서드도 가져온다.

<update id="boardOriginbidxUpdate" parameterType="int">
update board set originbidx = #{bidx} where bidx = #{bidx}
</update>

25. boardMapper.xml로 가서 업데이트 구문 쿼리 작성해준다.

26. 하나로 묶기 위해서 root.xml로 이동하면 sql세션 부분 밑에다가 트랜잭션을 사용하겠다는걸 등록해야하는데, 우선 namespace로 가서 체크해주기

27. impl로 가서 어노테이션으로 주입시키기. 하나로 묶어서 트랜잭션 하겠다. (근데 아직 빈에 등록 안했다.)

//게시판에서 글 작성과 파일 업로드 기능을 처리
	@RequestMapping(value= "boardWriteAction.aws")
	public String boardWriteAction(
		BoardVo bv, // 게시글 정보를 담고 있는 BoardVo 객체를 매개변수로 받음
		@RequestParam("filename") MultipartFile filename, // 업로드된 파일을 받기 위한 MultipartFile 객체
		HttpServletRequest request,
		RedirectAttributes rttr
		) throws Exception { // 윗단에 보고를 하는것
		MultipartFile file = filename; //저장된 파일 이름 꺼내기 
		String uploadedFileName=""; // 파일이 업로드된 후 저장된 파일명을 저장할 변수
		
		if(! file.getOriginalFilename().equals("")) { // 해당 파일이 존재한다면
			 // 파일을 서버에 저장하고 저장된 파일 이름을 반환받음
			uploadedFileName = UploadFileUtiles.uploadFile(uploadPath, file.getOriginalFilename(), file.getBytes());
		}
		String midx = request.getSession().getAttribute("midx").toString();
		int midx_int = Integer.parseInt(midx); 
		String ip = getUserIp(request);
		
		bv.setUploadedFilename(uploadedFileName);  // vo에 담아서 가져가기 
		bv.setMidx(midx_int);
		bv.setIp(ip);
		
		int value = boardService.boardInsert(bv);
		
		String path="";
		if(value == 2) { //성공하면
			path = "redirect:/board/boardList.aws";
		}else {
			rttr.addFlashAttribute("msg","입력이 잘못되었습니다.");
			path = "redirect:/board/boardWrite.aws"; // 리다이랙트로 넘기는것은 내부가 아니라 외부기 때문에 전체경로를 넘겨줘야 한다(aws)
		}
		
		return path;
	}

28. 마지막으로 BoardController에서 추가해주면 되는데 일단 전체 완성 코드

<%
String msg = "";
if(request.getAttribute("msg") != null) {
msg = (String)request.getAttribute("msg");
}

if(msg != "") {  
out.println("<script>alert('"+msg+"');</script>");
}

%>

29. boardWrite.jsp가서 상단에 msg 띄워주기

그리고 Vo에서 filename은 주석처리 해주기.
왜냐면 컨트롤러에서 @RequestParam("filename") MultipartFile filename 이렇게 객체를 받고 있기 때문에 필요가 없다!!!

그리고 스프링업로드에 파일이 두개나 들어가는것은 UploadFileUtiles클래스에 썸네일도 함께 만들어주기 때문에! 그래서 폴더 들어가서 이름을 확인해보면 썸네일에는 앞에 -s가 붙어있다.

0개의 댓글