본문 바로가기

일경험

[국민취업지원제도 일경험프로그램 26일차] 게시판 업로드 기능 완료, 게시판 첨부파일 다운로드 기능 구현 시작

반응형

26일 차 특이사항 

1. file_seq(게시글 최신 번호)를 가져왔는데 계속 오류가 나네? 정확히 어떤 쿼리문을 짜야하는 걸까? 

2. 오류 내용 

9월 06, 2023 11:12:45 오전 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: 경로 [/board]의 컨텍스트 내의 서블릿 [appServlet]을(를) 위한 Servlet.service() 호출이, 근본 원인(root cause)과 함께, 예외 [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='fileSeq', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting null for parameter #1 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 부적합한 열 유형: 1111]을(를) 발생시켰습니다.
java.sql.SQLException: 부적합한 열 유형: 1111

3. 도대체 뭐가 문제지? 이제는 realName을 인식 못한다고 한다. rsmap이 문제인가? 

 

4. 해결했다. 부적합한 열 유형 1111 이 나오는 경우는 mapper의 아이디값과 java에서 지정한 아이디 값이 다른 경우다. 이름을 같게 해 줘야 인식할 수 있다. java에 real_name이라고 이름을 붙여 놓고는 mapper에서 realName을 받고 있었다. 

 

5. 앞으로 넥사크로를 할지? 아니면 프로젝트를 할 것인가?

 

새로운과제 : 게시판 첨부파일 다운로드 

1. 업로드를 완료했으니 첨부파일 다운로드 기능을 만들어보자. 

- 2가지 방법이 있다고 한다. outputstream 혹은 jsp contentType

 

2. contentType을 다운로드로 바꿔줘야 한다. application/download 

3. Controller에 @response 사용 

4. 다운로드 할 때 파일명을 사용하려면 attachment 사용해야 함, 다운로드 이름 설정만 잘해주면 된다. 

 

5. 클릭했을 때, 파일에 대한 정보를 가지고 컨트롤러 백으로 가서 저장 경로를 매칭시켜서 outputstream으로 돌려주면 파일을 다운로드한다. 

 

6 업로드보다 쉽다? 

 

알게 된 점 

1. 게시글 번호의 최대값을 가져와서 사용했는데 위험할 수 있다. 컨트롤러에서 첨부파일 for문이 돌아가는데 그 사이에 누가 글을 올리면 글 번호가 바뀔 수 있다. 

<!-- seq 최대값 -->
<select id="selectSeq" parameterType="map" resultType="int">
 select max(seq) 
 from board_study 
</select>
 
2. 그런 경우 java의 싱크로나이즈드? 를 사용해서 동시 작업을 방지할 수 있다고 한다. 초급 과정은 아니니 지금은 mapper 를 수정하자. 
 
3. 쿼리문을 작성하고 이용하는 방법을 알게됐다. 컨트롤러에서 아래 쿼리문을 이용하여 게시판 일련번호, 파일 게시판 일련번호를 가져올 수 있다. 초기 값을 넣어주고 게시글이 추가될 때마다 갱신되는 구조를 만들었다. 
<!-- 게시판 seq 가져오기 -->
	<select id="listSeq" resultType="int">
	 select nvl(max(seq), 0)+1 
	 from board_study
	</select>
	
	<!-- 이미지 게시판 fileSeq 가져오기 -->
	<select id="fileSeq" resultType="int">
	 select nvl(max(file_seq), 0)+1 
	 from file_study_table
	</select>
	
	<!-- 글 등록하기 -->
	<insert id = "insert" parameterType="map">
		insert into board_study
		(
			seq
			,mem_name
			,mem_id
			,board_subject
			,board_content
			,reg_date
			,view_cnt
			,useyn
		)values(
			#{seq}
			,#{name}
			,#{id}
			,#{subject}
			,#{content}
			,sysdate
			,0
			,'y'
		)
	</insert>
	
	<!-- 이미지 등록 -->
	<insert id="fileinsert" parameterType="map">
	   insert into file_study_table
	   (
	       file_seq
	       ,real_name
	       ,save_name
	       ,save_path
	       ,reg_date
	       ,list_seq
	   )values( 
	       #{fileSeq}
	       ,#{realName}
	       ,#{saveName}
	       ,#{SAVE_PATH}
	       ,sysdate
	       ,#{listSeq} 
	   )
	</insert>

 

4. 글쓰기 컨트롤러

private static final String SAVE_PATH = "C:/Users/tmdgh/Desktop/img/";
	// 글쓰기 
	@RequestMapping("insert")
	public String insert(@RequestParam Map<String, Object> map, HttpServletRequest request, 
			MultipartHttpServletRequest mReq) throws IllegalStateException, IOException {
		
		
		int listSeq = sqlSession.selectOne("mapper.listSeq"); //  게시글 최신 번호를 가져온다.
		map.put("seq", listSeq);	// seq 값을 최신화 한다.
		int insert = service.insert(map); // 게시글을 저장한다. 

		int fileSeq = sqlSession.selectOne("mapper.fileSeq"); //10 
				
		System.out.println("fileSeq : " + fileSeq);
		System.out.println("listSeq : " + listSeq);
		
		Iterator<String> itr = mReq.getFileNames(); // 단일 여러개
		while (itr.hasNext()) {
		    MultipartFile mFile = mReq.getFile(itr.next());
		    	
		    String realName = mFile.getOriginalFilename();
		    String saveName = System.currentTimeMillis() + "_" + realName;
		    
		    System.out.println("mFile 들어오냐? : " + mFile);	
		    System.out.println("realName 들어오냐? : " + realName);
		    
		    mFile.transferTo(new File(SAVE_PATH + saveName));
		    
		    Map<String, Object> fileMap = new HashMap<String, Object>();
		    fileMap.put("fileSeq", fileSeq);
		    fileMap.put("realName", realName);
		    fileMap.put("saveName", saveName);
		    fileMap.put("SAVE_PATH", SAVE_PATH);
		    fileMap.put("listSeq", listSeq);
		    
		    int fileinsert = service.fileinsert(fileMap); // 파일 정보 저장 이게 문제야
		    	
		    System.out.println("itr에 뭐들었나 :" + itr);
		    System.out.println("fileMap에 뭐들었나 :" + fileMap);
		    System.out.println("fileinsert에 뭐들었나 :" + fileinsert);

		}	
		return "redirect:list";
	}

 

느낀 점

느리지만 결국 게시판 이미지 업로드 기능을 만들었다. 내일은 첨부파일 다운로드 기능을 구현해 볼 것이다. 찾아보니 여러 가지 방법이 있다. 어떤 방법이 좋을까? 일단 컨트롤러를 이용하는 방법을 해봐야겠다. 

 

 

 

반응형