Web

Ch13. MVC 4 : 날짜 값 변환

tose33 2022. 7. 25. 21:55

날짜를 이용한 회원 검색 기능, @DateTimeFormat

 

목표는 두 개의 날짜를 입력하면 그 사이에 가입한 회원들의 목록을 출력하는 것이다.

 

우선 MemberDao 클래스에 selectByRegdate() 메서드를 추가한다.

 

memberDao.java

	// 날짜를 이용한 회원 검색 
    // REGDATE가 from과 to 사이인 member 목록 리턴 
    public List<Member> selectByRegdate(
    		LocalDateTime from, LocalDateTime to)
    {
    	List<Member> results = jdbcTemplate.query(
    			"select * from MEMBER where REGDATE between ? and ? " +
    			"order by REGDATE desc", 
    			new RowMapper<Member>() 
    			{
    				@Override 
    				public Member mapRow(ResultSet rs, int rowNum) throws SQLException 
    				{
    					Member member = new Member(
    							rs.getString("EMAIL"),
    							rs.getString("PASSWORD"),
    							rs.getString("NAME"), 
    							rs.getTimestamp("REGDATE").toLocalDateTime()
    							);
    					member.setId(rs.getLong("ID"));
    					return member;
    				}
    			}, from, to);
    	return results;
    }

selectByRegdate() 메서드는 LocalDateTime형의 두 개의 날짜 데이터를 받고 쿼리를 이용해 DB에서 두 날짜 사이의 member의 목록을 리턴한다. 

 

 

다음은 커맨드 객체다.

ListCommand.java

package controller;

import java.time.LocalDateTime;

import org.springframework.format.annotation.DateTimeFormat;

public class ListCommand 
{
	@DateTimeFormat(pattern="yyyyMMddHH")
	private LocalDateTime from;
	@DateTimeFormat(pattern="yyyyMMddHH")
	private LocalDateTime to;
	
	public LocalDateTime getFrom() {
		return from;
	}
	public void setFrom(LocalDateTime from) {
		this.from = from;
	}
	public LocalDateTime getTo() {
		return to;
	}
	public void setTo(LocalDateTime to) {
		this.to = to;
	}
}

두 개의 필드 from,to에 @DateTimeFormat 애노테이션이 있다. 

 

목표는 두 개의 날짜를 입력하면 그 사이에 가입한 회원들의 목록을 출력하는 것이라고 했는데 입력을 받을때 jsp 파일에서 <input> 태그를 이용해 날짜를 입력받을 것이다. 그러면 입력 받은 문자열을 LocalDateTime 형으로 변환 해야 하는데, 이때 사용하는 것이 @DateTimeFormat 애노테이션이다. 

 

이렇게 커맨드 클래스의 LocalDateTime형 필드에 @DateTimeFormat 을 적용했다면, 컨트롤러에서는 그냥 해당 커맨드 객체를 사용하기만 하면 된다. 

 

 

컨트롤러 클래스

MemberListController.java

package controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import spring.Member;
import spring.MemberDao;

@Controller
public class MemberListController 
{
	private MemberDao memberDao;
	
	public void setMemberDao(MemberDao memberDao) 
	{
		this.memberDao = memberDao;
	}
	
	@RequestMapping("/members")
	public String list(@ModelAttribute("cmd") ListCommand listCommand, Model model) 
	{
		if(listCommand.getFrom() != null && listCommand.getTo() != null) 
		{
			List<Member> members = memberDao.selectByRegdate(listCommand.getFrom(), listCommand.getTo());
			model.addAttribute("members", members);
		}
		return "member/memberList";
	}
	

}

list() 메서드에서 커맨드 객체로 ListCommand를 사용하고 있다. 

memberDao.selectByRegdate() 메서드의 파라미터로 커맨드 객체 listCommand에서 날짜 데이터를 갖고와서 전달한다.

이미 커맨드 객체의 @DateTimeFormat 에 의해 LocalDateTime으로 변환이 된 상태이므로 그냥 전달해도 된다.

 

 

ControllerConfig 설정 클래스에 관련 빈들을 추가한다.

ControllerConfig.java

package config;

// ... 

@Configuration 
public class ControllerConfig 
{
	// MemberConfig.java에서 빈 객체로 추가됨   
    	// ... 
	@Autowired
	private MemberDao memberDao;
	
   	 // ...
    
	@Bean 
	public MemberListController memberListController() 
	{
		MemberListController controller = new MemberListController();
		controller.setMemberDao(memberDao);
		return controller;
	}
	
}

 

 

LocalDateTime 값을 원하는 형식으로 출력해주는 커스텀 태그 파일.

formatDateTime.tag

<%@ tag body-content="empty" pageEncoding="utf-8" %>
<%@ tag import="java.time.format.DateTimeFormatter" %>
<%@ tag trimDirectiveWhitespaces="true" %>
<%@ attribute name="value" required="true" 
              type="java.time.temporal.TemporalAccessor" %>
<%@ attribute name="pattern" type="java.lang.String" %>
<%
	if (pattern == null) pattern = "yyyy-MM-dd";
%>
<%= DateTimeFormatter.ofPattern(pattern).format(value) %>

 

 

뷰 

memberList.jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="tf" tagdir="/WEB-INF/tags" %>
    
<!DOCTYPE html>
<html>
<head>
	<title>회원 조회</title>
</head>
<body>

	<form:form modelAttribute="cmd">
	<p>
		<label>from:<form:input path="from" /></label>
		~
		<label>to:<form:input path="to" /></label>
		<input type="submit" value="조회">
	</p>		
	</form:form>
	
	<%-- from,to 입력 하지 않았을때는 members 존재하지 않음  --%>
	<c:if test="${!empty members }">
	<table>
		<tr>
			<th>아이디</th><th>이메일</th>
			<th>이름</th><th>가입일</th>
		</tr>
		<c:forEach var="mem" items="${members }">
		<tr>
			<td>${mem.id }</td>			
			<td><a href="<c:url value="/members/${mem.id }"/>"> ${mem.email} </a></td>
			<td>${mem.name } </td>
			<td> <tf:formatDateTime value="${mem.registerDateTime }" pattern="yyyy-MM-dd" /> </td>
		</tr> 
		</c:forEach>		
	</table>
	</c:if>

</body>
</html>

우선 <form:form>, <form:imput> 를 이용해 사용자에게서 날짜 두개를 입력받는다.

 

입력 전에는 "member"이 존재하지 않기 때문에 테이블을 보여주지 않다가, 입력이 존재할때 테이블을 보여준다.

 

 

 

 

 

출처 : 스프링5 프로그래밍 입문 (최범균 저)