[spring] 화면 처리 - 2

업데이트:



등록 입력 페이지와 등록 처리

게시물의 등록 잡업은 POST 방식으로 처리하지만, 화면에서 입력을 받아야 하므로 GET 방식으로 입력 페이지를 볼 수 있도록 BoardController.java에 메서드를 추가한다.

// BoardController.java

@GetMapping("/register")
public void register() {
    
}


register()는 입력 페이지를 보여주는 역할만 하기 때문에 별도의 처리가 필요하지 않다.

register.jsp 파일을 생성한다.
화면처리1

<!-- register.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<%@include file="../includes/header.jsp"%>

<div class="row">
	<div class="col-lg-12">
		<h1 class="page-header">Board Register</h1>
	</div>
	<!-- /.col-lg-12 -->
</div>
<!-- /.row -->

<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">

			<div class="panel-heading">Board Register</div>
			<!-- /.panel-heading -->
			<div class="panel-body">

				<form role="form" action="/board/register" method="post">
					<div class="form-group">
						<label>Title</label> <input class="form-control" name="title">
					</div>
					
					<div class="form-group">
						<label>Text area</label>
						<textarea rows="3" class="form-control" name="content"></textarea>
					</div>
					
					<div class="form-group">
						<label>Writer</label> <input class="form-control" name="writer">
					</div>
					
					<button type="submit" class="btn btn-default">Submit
						Button</button>
					<button type="reset" class="btn btn-default">Reset Button</button>
				</form>

			</div>
			<!--  end panel-body -->

		</div>
		<!--  end panel-body -->

	</div>
	<!--  end panel -->

</div>
<!--  end row -->

<%@ include file="../includes/footer.jsp"%>


input이나 textarea 태그의 name 속성은 BoardVO 클래스의 변수와 일치시켜준다.

화면처리2



BoardController의 POST 방식으로 동작하는 register()는 redirect 시키는 방식을 이용하므로, 게시글 등록 후에는 다시 ‘/board/list’로 이동하게 된다.

화면처리3

화면처리4


등록은 정상적으로 이루어지지만 한글이 깨진다.





한글 문제와 UTF-8 필터 처리

한글 입력에 문제가 있다면 브라우저에서 한글이 깨져서 전송되는지 확인 후 문제가 없다면 스프링 MVC쪽에서 한글을 처리하는 필터를 등록해야한다.


브라우저에서 전송되는 데이터는 개발자 도구를 통해서 확인할 수 있다. Network 탭을 열고 다시 게시물을 등록하면 한글이 깨졌는지 확인할 수 있다.

화면처리5

브라우저에서 한글이 깨지지 않았다. 즉, Controller 혹은 데이터베이스 쪽에서 문제가 발생함을 알 수 있다.

BoardController와 BoardServiceImpl에서 로그를 확인한다.
화면처리6

BoardController에 전달될 때 이미 한글이 깨진 상태로 처리된 것을 확인할 수 있다.

문제 해결

<!-- web.xml -->

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

web.xml 적용 후 다시 게시물을 작성하면 한글이 정상적으로 출력된다.

화면처리7





재전송(redirect) 처리

등록, 수정, 삭제 작업은 처리가 완료된 후 다시 동일한 내용을 전송할 수 없도록 아예 브라우저의 URL을 이동하는 방식을 사용한다. 이러한 과정에서 하나 더 신경 써야 하는 것은 브라우저에 등록, 수정, 삭제 결과를 바로 알 수 있게 피드백을 줘야한다.

BoardController에서 redirect 처리를 할 때 addFlashAttribute()가 적합하다. 그 이유는 일회성으로만 데이터를 전달하기 때문이다.

list.jsp에 script를 작성한다.

<script type="text/javascript">
	$(document).ready(function() {
		var result = '<c:out value="${result}"/>';
	})
</script>

화면처리8


새로운 게시물의 번호는 addFlashAttribute()로 저장되었기 때문에 한 번도 사용된 적이 없다면 위와 같이 값을 만들어 내지만 사용자가 ‘/board/list’를 호출하거나, 새로고침을 통해 호출하는 경우는 아래와 같이 아무런 내용이 없게 된다.

화면처리9





모달(Model)창 보여주기

모달 코드는 SB Admin2의 page 폴더 내 notifications.html 파일에서 찾아서 복사하고, list.jsp 파일 table 태그 밑에 붙여넣기 하면 된다고 써져있었는데 계속 모달창이 안떠서 그냥 스트립트 태그 위에 붙여넣었다.

<!-- list.jsp -->

		<!-- Model 추가 -->
		<!-- Modal -->
		<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
			aria-labelledby="myModalLabel" aria-hidden="true">
			<div class="modal-dialog">
				<div class="modal-content">
					<div class="modal-header">
						<button type="button" class="close" data-dismiss="modal"
							aria-hidden="true">&times;</button>
						<h4 class="modal-title" id="myModalLabel">Modal title</h4>
					</div>
					<div class="modal-body">처리가 완료되었습니다.</div>
					<div class="modal-footer">
						<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
						<button type="button" class="btn btn-primary">Save changes</button>
					</div>
				</div>
				<!-- /.modal-content -->
			</div>
			<!-- /.modal-dialog -->
		</div>
		<!-- /.modal -->

<script type="text/javascript">
	$(document).ready(
			function() {
				var result = '<c:out value="${result}"/>';
				checkModal(result);

				function checkModal(result) {
					if (result === '') {
						return;
					}

					if (parseInt(result) > 0) {
						$(".modal-body").html(
								"게시글  " + parseInt(result) + "번이 등록되었습니다.");

					}
					$("#myModal").modal("show");
				}
			});
</script>


화면처리10

모달창이 안 뜨는 문제 빼고 또 다른 문제가 있었는데, bno가 1씩 증가되는게 아니라 2씩 증가되는 문제도 있었다. 그래서 울면서 다시..쳤다는….슬픈 얘기. 혹시 나처럼 1씩 증가가되는게 아니라 마음대로 증가된다면 아래의 코드로 복붙을 추천한다. 코드는 맨 아래에 있다. 이동


모달이 안뜨면 제일 먼저 $("#myModal").modal("show")이 부분의 아이디와 모달 제일 처음 div 태그 id가 같은지 확인하고, 같다면 헤더나 푸터에 있는 부트스트랩 경로를 확인하면 될 것이다..아마..





목록에서 버튼으로 이동하기

<!-- list.jsp 수정 -->

<div class="panel panel-default">
	<div class="panel-heading">Board List Page
		<button id='regBtn' type="button" 
			class="btn btn-xs pull-right">Register New Board</button>
	</div>
	<!-- /.panel-heading -->


화면처리11

지금 상태에서 누르면 아무 동작도 안한다.
list.jsp 하단에 jQuery를 이용해 동작시킨다.

<!-- list.jsp 스크립트 추가 -->

$("#regBtn").on("click", function(){
	self.location ="/board/register";
});


위의 코드 작성 후 버튼을 누르면 /board/register 경로로 이동한다.

코드 모음

모달 적용 전인 코드

  • BoardController.java
package org.zerock.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.zerock.domain.BoardVO;
import org.zerock.service.BoardService;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

@Controller
@Log4j
@RequestMapping("/board/*") // 보드로 시작하는 모든 처리를 BoardController가 하도록 처리
@AllArgsConstructor // 생성자에 의존성 주입
public class BoardController {
	private BoardService service;
	
	@GetMapping("/list")
	public void list(Model model) {
		log.info("list");
		model.addAttribute("list", service.getList());
	}
	@PostMapping("/register")
	public String register(BoardVO board, RedirectAttributes rttr) {
		log.info("register: "+board);
		service.register(board);
		
		rttr.addFlashAttribute("result", board.getBno());
		
		return "redirect:/board/list";
	}
	@GetMapping("/get")
	public void get(@RequestParam("bno") Long bno, Model model) {
		log.info("/get");
		model.addAttribute("board", service.get(bno));
	}
	@PostMapping("/modify")
	public String modify(BoardVO board, RedirectAttributes rttr) {
		log.info("modify: "+board);
		
		if(service.modify(board)) {
			rttr.addFlashAttribute("result", "success");
		}
		return "redirect:/board/list";
	}
	@PostMapping("/remove")
	public String remove(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
		log.info("remove....."+bno);
		if (service.remove(bno)) {
			rttr.addFlashAttribute("result", "success");
		}
		return "redirect:/board/list";
		
	}
	@GetMapping("/register")
	public void register() {
		
	}
}


  • src/main/java/org.zerock.mapper.BoardMapper.java
package org.zerock.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.zerock.domain.BoardVO;

public interface BoardMapper {
	//@Select("SELECT * FROM tbl_board WHERE bno > 0")
	public List<BoardVO> getList();
	
	public void insert(BoardVO board);
	
	public void insertSelectKey(BoardVO board);
	
	public BoardVO read(Long bno);
	
	public int delete(Long bno);
	
	public int update(BoardVO board);
}


  • BoardService.java
package org.zerock.service;

import java.util.List;

import org.zerock.domain.BoardVO;

public interface BoardService {

	public void register(BoardVO board);
	
	public BoardVO get(Long bno);
	
	public boolean remove(Long bno);
	
	public List<BoardVO> getList();

	public boolean modify(BoardVO board);
}


  • BoardServiceImpl.java
package org.zerock.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.BoardVO;
import org.zerock.mapper.BoardMapper;

import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService{
	@Setter(onMethod_ = @Autowired)
	private BoardMapper mapper;
	
	@Override
	public void register(BoardVO board) {
		log.info("register....."+board);
		mapper.insertSelectKey(board);
	}

	@Override
	public BoardVO get(Long bno) {
		log.info("get......."+bno);
		return mapper.read(bno);
	}

	@Override
	public boolean remove(Long bno) {
		log.info("remove....."+bno);
		return mapper.delete(bno) == 1;
	}

	@Override
	public List<BoardVO> getList() {
		log.info("getList......");
		return mapper.getList();
	} 
	@Override
	public boolean modify(BoardVO board) {
		log.info("modify....."+board);
		return mapper.update(board)==1;
	}
}


  • src/main/resources/org/zerock/mapper/BoardMapper.xml (아마 제일 유력한 용의자..)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.zerock.mapper.BoardMapper">
	<select id="getList" resultType="org.zerock.domain.BoardVO">
		<![CDATA[select * from tbl_board where bno>0]]>
	</select>
	
	<insert id= "insert" >
		insert into tbl_board(bno, title, content, writer)
		values (seq_board.nextval, #{title}, #{content}, #{writer})
	</insert>
	
	<insert id="insertSelectKey">
		<selectKey keyProperty="bno" order="BEFORE" resultType="long">
			select seq_board.nextval from dual
		</selectKey>
		
		insert into tbl_board (bno, title, content, writer)
		values (#{bno}, #{title}, #{content}, #{writer})
	</insert>
	
	<select id="read" resultType="org.zerock.domain.BoardVO">
		select * from tbl_board where bno=#{bno}
	</select>
	<delete id="delete" >
		delete from tbl_board where bno = #{bno}
	</delete>
	<update id="update">
		update tbl_board
		set title=#{title},
		content = #{content},
		writer = #{writer},
		updateDate = sysdate
		where bno = #{bno}
	</update>
</mapper>







  • 참고 : 코드로 배우는 스프링 웹 프로젝트

태그:

카테고리:

업데이트:

댓글남기기