Java Spring JSP웹페이지 만들기5(글쓰기 페이지 만들기)

호연지기·2023년 5월 25일
0
post-thumbnail

📌 글쓰기 페이지 만들기 (writeForm)

게시글 목록 페이지에서 글쓰기 버튼을 누르면 글쓰기 페이지로 이동한다. 내용을 입력하면 데이터베이스에 저장 처리까지!(파일 업로드 기능)

✏ 작업 순서

css와 데이터베이스 자료는 생성되어 있던 것 사용

  1. 글쓰기 페이지가 될 jsp 파일을 생성( writeForm.jsp )
  2. 컨트롤러에서 글쓰기 페이지 이동, 글쓰기 처리 메소드 생성, 멀티파트 데이터 받아오는 매개변수 설정( BoardController )
  3. 글쓰기 작업 처리( BoardService , BoardDao)
  4. 파일 업로드 처리( BoardService, BoardDao )
  5. 글쓰면 회원 포인트 증가 (BoardService, MemberDao )

File upload
HTML의 <input> 태그의 file type은 기본적인 파일 선택 창을 제공.

Multi-part
한 웹 문서 안에 문자와 바이너리 데이터(이미지, 동영상, 음성 및 기타 형식의 파일 등)가 함께
포함되어 있는 상황.

MIME(Multipurpose Internet Mail Extenstion)
전자우편(e-mail)을 위한 인터넷 표준 포맷.
content-type : 문서에 포함된 내용을 구성한 형태 지정.
기본 형태 - text/plain이나 text/html.
다중의 내용이 포함되면 multipart/...

💫 글쓰기 페이지 생성(JSP)

💻 writeForm 소스

<section>
    <div class="content">
        <form action="writeProc" class="write-form" method="post" enctype="multipart/form-data">
            <div class="user-info">
                <div class="user-info-sub">
                    <p>등급 [${mb.g_name}]</p>
                    <p>POINT [${mb.m_point}]</p>
                </div>
            </div>
            <h2 class="login-header">글쓰기</h2>
            <!-- 로그인한 id(숨김), 제목, 내용 -->
            <input type="hidden" name="b_id" value="${mb.m_id}">
            <input type="text" class="write-input" name="b_title"
            autofocus placeholder="제목" required>
            <textarea name="b_contents" class="write-input ta" rows="15" placeholder="내용을 적어주세요."></textarea>
            <div class="filebox">
                <label for="file">업로드</label>
                <input type="file" name="files" id="file" multiple>
                <input type="text" class="upload-name" value="파일선택" readonly>

            </div>
            <div class="btn-area">
                <input type="submit" class="btn-write" value="W">
                <input type="reset" class="btn-write" value="R">
                <input type="button" class="btn-write" value="B" onclick="backbtn()">
            </div>
        </form>
    </div>
</section>

B 버튼 클릭시 뒤로 이동할 스크립트와 파일 업로드시 파일 제목처리용 함수가 필요하다.

💻 writeForm 소스 (script 영역)

//B 버튼 클릭시 뒤로 가는 스크립트
function backbtn(){
    let urlstr = "/list?";
    let col = "${sdto.colname}";
    let keyw = "${sdto.keyword}";

    if(col == null || col == ''){//검색을 수행하지 않은 경우
        urlstr += "pageNum=${pageNum}";
    } else{//검색을 한 경우
        urlstr += "colname=${sdto.colname}&keyword=${sdto.keyword}&pageNum=${sdto.pageNum}";
    }
    console.log(urlstr);
    location.href = urlstr;
}

//파일 제목 처리용 함수
$("#file").on("change",function(){
   //파일 선택 창에서 업로드할 파일을 선택한 후 '열기' 버튼을 누르면 change 이벤트가 발생.
    console.log($("#file"));

    let files = $("#file")[0].files;
    console.log(files);

    let fileName = "";
    if(files.length > 1){
        fileName = files[0].name + " 외 " + (files.length -1) + "개";
    } else if(files.length == 1){
        fileName = files[0].name;
    } else {
        fileName = "파일선택";
    }
    $(".upload-name").val(fileName);
});

파일이 한 개만 업로드 될 때는 파일명 그대로 노출

파일이 한 개 이상일 때는 맨 처음에 업로드 한 파일의 이름만 노출되고 나머지는 외 n개로 표현한다.

💫 컨트롤러 작업 (글쓰기 페이지 이동, 글쓰기 처리 메소드 생성, 멀티파트 데이터 받아오는 매개변수 설정)

💻 BoardController 소스

//글쓰기 페이지 이동 메소드
@GetMapping("writeForm")
public String writeForm(){
    log.info("writeForm()");
    return "writeForm";
}

//글쓰기 작업 처리 메소드
//멀티파트 데이터를 처리하는 메소드의 첫번째 매개변수는
//Multipart 파일 목록(List)여야 한다.
//List 앞에 @RequestPart 어노테이션을 붙인다.
@PostMapping("writeProc")
public String writeProc(@RequestPart List<MultipartFile> files,
                        BoardDto board, HttpSession session,
                        RedirectAttributes rttr){
    log.info("writeProc()");
    String view = bServ.boardWrite(files, board, session, rttr);
    return view;
}

💫 글쓰기 작업 처리

💻 BoardService 소스


public String boardWrite(List<MultipartFile> files, BoardDto board, HttpSession session, RedirectAttributes rttr){
    log.info("boardWrite()");
    String view = null;
    String msg = null;

    try {
        //글 내용 저장.
        bDao.insertBoard(board);
        log.info("게시글 번호 : " + board.getB_num());

        //파일 업로드 처리
        fileUpload(files, session, board);

        //작성한 회원의 point 증가 처리(session)
        MemberDto member = (MemberDto) session.getAttribute("mb");
        int point = member.getM_point() + 10;
        if(point > 100){//100 초과하지 않도록
            point = 100;
        }
        member.setM_point(point);
        //DB member 테이블 수정(update)
        mDao.updateMemberPoint(member);
        session.setAttribute("mb", member);
        //같은 이름으로 세션에 저장하면 덮어쓰기가 된다.

        //글 작성 후 목록 첫 페이지로 이동.
        view = "redirect:list?pageNum=1";
        msg = "글 작성 성공";
    } catch (Exception e){
        e.printStackTrace();
        view = "redirect:writeForm";
        msg = "글 작성 실패";
    }
    rttr.addFlashAttribute("msg", msg);
    return view;
}

💻 BoardDao.java 소스

@Mapper
public interface BoardDao {
	//게시글 저장 메소드 선언
	void insertBoard(BoardDto board);
}

💻 BoardDao.xml 소스

DB에 사용자가 입력한 내용을 저장하는 쿼리문


<insert id="insertBoard" parameterType="BoardDto"
        useGeneratedKeys="true" keyProperty="b_num">
    <selectKey keyProperty="b_num" resultType="Integer" order="AFTER">
        select last_insert_id()
    </selectKey>
        insert into board values (null, #{b_title}, #{b_contents}, #{b_id}, default, default)
</insert>

💫 파일 업로드 작업 처리

BoardService 소스에서 파일 업로드 메소드를 사용하는 부분은 글쓰기 작업 처리 영역에 포함되어 있어서 생략한다.

//파일 업로드 처리 <- 이 부분
fileUpload(files, session, board);

💻 BoardService 소스 (파일 업로드)


private void fileUpload(List<MultipartFile> files, HttpSession session, BoardDto board) throws Exception{
    log.info("fileUpload()");
    //파일 저장 위치
    String realPath = session.getServletContext().getRealPath("/");
    realPath += "upload/"; //업로드용 폴더 : upload
    File folder = new File(realPath);
    if(folder.isDirectory() == false){
        folder.mkdir();//폴더 생성.
    }

    //파일 저장 처리(목록이므로 반복 처리)
    for(MultipartFile mf : files){
        //파일명(원래 이름) 추출
        String orname = mf.getOriginalFilename();
        if(orname.equals("")){
            return;
        }

        //파일 정보 저장
        BfileDto bf = new BfileDto();
        bf.setBf_bnum(board.getB_num());//게시글 번호
        bf.setBf_oriname(orname);//원래 파일 이름
        String sysname = System.currentTimeMillis()
                + orname.substring(orname.lastIndexOf("."));
        bf.setBf_sysname(sysname);

        //파일 저장(to upload folder)
        File file = new File(realPath + sysname);
        mf.transferTo(file);

        //파일 정보 저장(DB)
        bDao.insertFile(bf);

    }//for end
}//method end

💻 BoardDao.java 소스

@Mapper
public interface BoardDao {
    //게시글 파일 저장 메소드
    void insertFile(BfileDto df);
}

💻 BoardDao.xml 소스

<insert id="insertFile" parameterType="BfileDto">
    insert into boardfile
    values (null, #{bf_bnum}, #{bf_oriname}, #{bf_sysname})
</insert>

웹 페이지

아직 상세보기 페이지를 만들지는 않았지만 파일 업로드를 하면 페이지에 업로드된 이미지 파일명이 보인다. 중복 파일명 업로드를 피하기 위해 DB에는 파일명을 바꿔서 업로드 한다.

데이터베이스

bf_oriname : 원래의 파일 이름
bf_sysname : DB에 저장된 파일 이름

💫 글쓰기 후 회원 포인트 증가 작업

BoardService 소스에서 회원 포인트 증가 메소드를 사용하는 부분은 글쓰기 작업 처리 영역에 포함되어 있어서 생략한다.

//작성한 회원의 point 증가 처리(session) <- 이 부분
MemberDto member = (MemberDto) session.getAttribute("mb");
int point = member.getM_point() + 10;
if(point > 100){//100 초과하지 않도록
    point = 100;
}
member.setM_point(point);
//DB member 테이블 수정(update)
mDao.updateMemberPoint(member);
session.setAttribute("mb", member);
//같은 이름으로 세션에 저장하면 덮어쓰기가 된다.

MemberDto의 member를 불러와서 글을 쓴 회원의 포인트를 증가시킨다. 최대 포인트는 100점. (100점 이상 넘어가지 않도록 조절)

💻 MemberDao.java 소스

@Mapper
public interface MemberDao {
    //회원 포인트 수정 메소드
    void updateMemberPoint(MemberDto member);
}

💻 MemberDao.xml 소스

<update id="updateMemberPoint">
    update member
    set m_point=#{m_point}
    where m_id=#{m_id}
</update>

계속 글쓰기 테스트를 해보다 어느새 다이아 등급이 되어버린 나...

📅 DATE

2023.05.25 작성

profile
사람의 마음에 차 있는 너르고 크고 올바른 기운

0개의 댓글