스프링 MVC3_ 세션

 

로그인 성공 후 인증 상태 정보를 세션에 보관할 때 사용할 클래스 생성

package spring;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@AllArgsConstructor
@Getter
@Setter
@ToString
@NoArgsConstructor
public class AuthInfo {
	private Long id;
	private String email;
	private String name;
	
}

 

암호 일치여부 확인 및 기본 DTO

package spring;

import java.time.LocalDateTime;

public class Member {

	private Long id;
	private String email;
	private String password;
	private String name;
	private LocalDateTime registerDateTime;

	public Member(String email, String password, 
			String name, LocalDateTime regDateTime) {
		this.email = email;
		this.password = password;
		this.name = name;
		this.registerDateTime = regDateTime;
	}

	void setId(Long id) {
		this.id = id;
	}

	public Long getId() {
		return id;
	}

	public String getEmail() {
		return email;
	}

	public String getPassword() {
		return password;
	}

	public String getName() {
		return name;
	}

	public LocalDateTime getRegisterDateTime() {
		return registerDateTime;
	}

	public void changePassword(String oldPassword, String newPassword) {
		if (!password.equals(oldPassword))
			throw new WrongIdPasswordException();
		this.password = newPassword;
	}
	
	public boolean mathPassword(String password) {
		return this.password.equals(password);
	}

}

 

 

DAO

package spring;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

public class MemberDao {

	private JdbcTemplate jdbcTemplate;

	public MemberDao(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	public Member selectByEmail(String email) {
		List<Member> results = jdbcTemplate.query(
				"select * from MEMBER where EMAIL = ?",
				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;
					}
				}, email);

		return results.isEmpty() ? null : results.get(0);
	}







}

 

 

이메일 비밀번호 일치 확인 후 객체를 생성하는 서비스 클래스 생성

package spring;

public class AuthService {
	
	private MemberDao memberDao;
	
	
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	
	public AuthInfo authenticate(String email, String password) {
		Member member = memberDao.selectByEmail(email);
		if(member == null) {
			throw new WrongIdPasswordException();
		}
		
		if(!member.mathPassword(password)) {
			throw new WrongIdPasswordException();
		}
		return new AuthInfo(member.getId(),
							member.getEmail(),
							member.getName());
		
	}
	
}

 

 

에러처리

package spring;

public class WrongIdPasswordException extends RuntimeException {

}

 

 

폼에 입력한 값을 전달받기 위한 Login커맨드 클래스 생성

package controller;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString



public class LoginCommand {
	
	private String email;
	private String password;
	private boolean rememberEmail;
	
	
	public boolean isRememberEmail() {
		return rememberEmail;
	}
	
	public void setRememberEmail(boolean rememberEmail) {
		this.rememberEmail = rememberEmail;
	}
	
}

 

 

입력값이 올바른지 확인하기 위한 Validator 클래스 생성

package controller;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class LoginCommandValidator implements Validator {

	@Override
	public boolean supports(Class<?> clazz) {
		
		return LoginCommand.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "required");
		ValidationUtils.rejectIfEmpty(errors, "password", "required");
		
	}
	
	

}

 

 

로그인 요청 처리 controller 클래스 생성 ( 세션정보 저장 )

package controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import lombok.extern.slf4j.Slf4j;
import spring.AuthInfo;
import spring.AuthService;
import spring.WrongIdPasswordException;

@Controller
@RequestMapping("/login")
@Slf4j
public class LoginController {
	private AuthService authService;
	
	public void setAuthService(AuthService authService) {
		this.authService = authService;
	}
	
	@GetMapping
	public String form(LoginCommand loginCommand) {
		return "login/loginForm";
	}
	
	@PostMapping
	public String submit(LoginCommand loginCommand, Errors errors, HttpSession session) {
		new LoginCommandValidator().validate(loginCommand, errors);
		
		if(errors.hasErrors()) {
			return "login/loginForm";
		}
		try {
			AuthInfo authInfo = authService.authenticate(loginCommand.getEmail(),
															loginCommand.getPassword());
			
			// 로그인 session 테스트
			session.setAttribute("authInfo", authInfo);
			session.setAttribute("test", authInfo);
			AuthInfo authInfo1 = (AuthInfo) session.getAttribute("authInfo");
			log.info("-----login------->" + authInfo1);
			
			
			
			return "login/loginSuccess";
		} catch (WrongIdPasswordException e) {
			errors.reject("idPasswordNotMatching");
			return "login/loginForm";
		}
	}
	
	
}

 

 

로그아웃 controller

package controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import lombok.extern.slf4j.Slf4j;
import spring.AuthInfo;

@Controller
@Slf4j
public class LogoutController {
	@RequestMapping("/logout")
	public String logout(HttpSession session) {
		
		
		// 로그아웃 session 테스트
		AuthInfo authInfo = (AuthInfo) session.getAttribute("authInfo");
		log.info("------logout------>" + authInfo);
		session.invalidate();
		

		
		return "redirect:/main";
	}
}

 

 

컨트롤러, 서비스 스프링 빈 등록

package config;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import controller.LogoutController;
import spring.AuthService;
import spring.MemberDao;

@Configuration
@EnableTransactionManagement
public class MemberConfig {

	@Bean(destroyMethod = "close")
	public DataSource dataSource() {
		DataSource ds = new DataSource();
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost/spring5fs?characterEncoding=utf8");
		ds.setUsername("spring5");
		ds.setPassword("spring5");
		ds.setInitialSize(2);
		ds.setMaxActive(10);
		ds.setTestWhileIdle(true);
		ds.setMinEvictableIdleTimeMillis(60000 * 3);
		ds.setTimeBetweenEvictionRunsMillis(10 * 1000);
		return ds;
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		DataSourceTransactionManager tm = new DataSourceTransactionManager();
		tm.setDataSource(dataSource());
		return tm;
	}

	@Bean
	public MemberDao memberDao() {
		return new MemberDao(dataSource());
	}


	
	@Bean
	public AuthService authService() {
		AuthService authService = new AuthService();
		authService.setMemberDao(memberDao());
		return authService;
	}
	
	@Bean
	public LogoutController logoutController() {
		return new LogoutController();
	}
}

 

 

package config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import controller.LoginController;
import spring.AuthService;

@Configuration
public class ControllerConfig {


	
	@Autowired
	private AuthService authService;
	
	@Bean
	public LoginController loginController() {
		LoginController controller = new LoginController();
		controller.setAuthService(authService);
		return controller;
	}
}
package config;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

	@Override
	public void configureDefaultServletHandling(
			DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/view/", ".jsp");
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/main").setViewName("main");
	}

	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource ms = 
				new ResourceBundleMessageSource();
		ms.setBasenames("message.label");
		ms.setDefaultEncoding("UTF-8");
		return ms;
	}

	
}

 

스프링 메세지

member.register=회원가입

term=약관
term.agree=약관동의
next.btn=다음단계

member.info=회원정보
email=이메일
name=이름
password=비밀번호
password.confirm=비밀번호 확인
register.btn=가입 완료

register.done=<strong>{0}님 ({1})</strong>, 회원 가입을 완료했습니다.

go.main=메인으로 이동

required=필수항목입니다.
bad.email=이메일이 올바르지 않습니다.
duplicate.email=중복된 이메일입니다.
nomatch.confirmPassword=비밀번호와 확인이 일치하지 않습니다.

login.title = 로그인
login.btn = 로그인하기
idPasswordNotMatching=아이디와 비밀번호가 일치하지 않습니다.
login.done=로그인에 성공했습니다.

 

 

main.jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>메인</title>
</head>
<body>
	<c:if test="${empty authInfo }">
    <p>환영합니다.</p>
    <p><a href="<c:url value="/register/step1" />">[회원 가입하기]</a>
	<a href="<c:url value="/login"/>">[로그인]</a>
	</p>
	</c:if>
	
	<c:if test="${! empty authInfo }">
    <p>${authInfo.name}님,  환영합니다.</p>
    <p><a href="<c:url value="/edit/changePassword" />">[비밀번호 변경]</a>
	<a href="<c:url value="/logout"/>">[로그아웃]</a>
	</p>
	</c:if>
	
</body>
</html>

 

loginForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><spring:message code="login.title" /></title>
</head>
<body>
<form:form modelAttribute="loginCommand">
<form:errors />
<p>
<label><spring:message code="email" />:<br>
<form:input path="email" />
<form:errors path="email" />
</label>
</p>

<p>
<label>
<spring:message code="password" />:<br>
<form:password path="password" />
<form:errors path="password" />
</label>
</p>
<input type="submit" value="<spring:message code="login.btn" />">

</form:form>
</body>
</html>

 

loginSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><spring:message code="login.title" /></title>
</head>
<body>
<p>
<spring:message code="login.done" />
</p>

<p>
<a href="<c:url value='/main'/>">
[<spring:message code="go.main" />]
</a>
</p>
</body>
</html>

스프링 MVC2_ 글로벌 범위 Validator와 컨트롤러 범위 Validator

글로벌 범위는 모든 컨트롤러에 적용할 수있는 Validator

 

 

글로벌 범위 Validator

 

1. 설정 클래스에서 getValidator() 메서드가 Validator 구현 객체를 리턴하도록 설정

 

설정 클래스

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
    
    @Override // 컨트롤러 기능을 대신 해줌 
	// 글로벌 범위 
	public Validator getValidator() { // 소스 => 오버라이드
		
		return new RegisterRequestValidator();
	}
    }

 Validator 구현 객체

package controller;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import spring.RegisterRequest;

public class RegisterRequestValidator implements Validator {
	
	private static final String emailRegExp = 
			"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" +
					"[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	private Pattern pattern;
	
	public RegisterRequestValidator() {
		pattern = Pattern.compile(emailRegExp);
	}
	
	@Override
	public boolean supports(Class<?> clazz) {
		     // 대상이 되는 커맨드 객체
		return RegisterRequest.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		RegisterRequest regReq = (RegisterRequest) target;
		if(regReq.getEmail() == null  || regReq.getEmail().trim().isEmpty()) {
			errors.rejectValue("email", "required");
		}else {
			Matcher matcher = pattern.matcher(regReq.getEmail());
			if(!matcher.matches()) {
				errors.rejectValue("email", "bad");
			}
		}
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required");
		ValidationUtils.rejectIfEmpty(errors, "password", "required");
		ValidationUtils.rejectIfEmpty(errors, "confirmPassword", "required");
		if(!regReq.getPassword().isEmpty()) {
			if(!regReq.isPasswordEqualToConfirmPassword()) {
				errors.rejectValue("confirmPassword", "nomatch");
			}
		}
		
		
	}

}

 

 

2. 글로벌 범위 Validator가 검증할 커맨드 객체에 @Valid 애노테이션 적용

Errors 타입 파라미터 넣을 것

	@PostMapping("/register/step3") // BindingResult = Errors 동일 
	public String handleStep3(@Valid RegisterRequest regReq, BindingResult errors) {
		// 컨트롤러 범위
        // RegisterRequestValidator() 생성안해도 됨
//		new RegisterRequestValidator().validate(regReq, errors);
		if(errors.hasErrors()) {
			return "register/step2";
		}
		
		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		} catch (DuplicateMemberException ex) {
			
			return "register/step2";
		}
	}

메이븐이면 pom.xml에 dependency 추가

		<dependency>
		<groupId>javax.validation</groupId>
		<artifactId>validation-api</artifactId>
		<version>2.0.1.Final</version>
		</dependency>

 

 

 

@InitBinder 애노테이션을 이용한 컨트롤러 범위 Validator

@Valid 애노테이션으로 범위 지정 

위에 글로벌 범위 지정 설정 클래스 메서드 지워도 됨

	@PostMapping("/register/step3") // BindingResult = Errors 동일 
	public String handleStep3(@Valid RegisterRequest regReq, BindingResult errors) {
		// 컨트롤러 범위 
		// RegisterRequestValidator() 생성안해도 됨
		if(errors.hasErrors()) {
			return "register/step2";
		}
		
		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		} catch (DuplicateMemberException ex) {
			
			return "register/step2";
		}
	}
	
	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.setValidator(new RegisterRequestValidator());
	}

 

 

 

Bean Validation을 이용한 값 검증 처리

이 애노테이션을 사용하면 Validator 작성 없이 애노테이션만으로 커맨드 객체의 값 검증을 처리할 수 있다.

 

1. Bean Validation과 관련된 의존을 설정에 추가

		<dependency>
		<groupId>javax.validation</groupId>
		<artifactId>validation-api</artifactId>
		<version>2.0.1.Final</version>
		</dependency>
		
		<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-validator</artifactId>
		<version>6.0.7.Final</version>
		</dependency>

 

커맨드 객체에 @NotNull, @Digits 등의 애노테이션을 이용해서 검증 규칙 설정

 

package spring;

import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;

public class RegisterRequest {
	
	@NotBlank
	@Email
	private String email;
	@Size(min = 6)
	private String password;
	@NotEmpty
	private String confirmPassword;
	@NotEmpty
	private String name;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isPasswordEqualToConfirmPassword() {
		return password.equals(confirmPassword);
	}
}

 

3. 글로벌 범위 @EnableWebMvc 설정

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

 

 

4. @Valid 애노테이션을 붙여서 글로벌 범위 Validator로 검증

	@PostMapping("/register/step3") // BindingResult = Errors 동일 
	public String handleStep3(@Valid RegisterRequest regReq, BindingResult errors) {
		// 컨트롤러 범위 

		if(errors.hasErrors()) {
			return "register/step2";
		}
		
		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		} catch (DuplicateMemberException ex) {
			
			return "register/step2";
		}
	}

 

JSP

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
    <title><spring:message code="member.register" /></title>
</head>
<body>
    <h2><spring:message code="member.info" /></h2>
    <form:form action="step3" modelAttribute="registerRequest">
    <p>
        <label><spring:message code="email" />:<br>
        <form:input path="email" />
        <form:errors path="email" />
        </label>
    </p>
    <p>
        <label><spring:message code="name" />:<br>
        <form:input path="name" />
        <form:errors path="name" />
        </label>
    </p>
    <p>
        <label><spring:message code="password" />:<br>
        <form:password path="password" />
        <form:errors path="password" />
        </label>
    </p>
    <p>
        <label><spring:message code="password.confirm" />:<br>
        <form:password path="confirmPassword" />
        <form:errors path="confirmPassword" />
        </label>
    </p>
    <input type="submit" value="<spring:message code="register.btn" />">
    </form:form>

<%--
    <form action="step3" method="post">
    <p>
        <label>이메일:<br>
        <input type="text" name="email" id="email" value="${registerRequest.email}">
        </label>
    </p>
    <p>
        <label>이름:<br>
        <input type="text" name="name" id="name" value="${registerRequest.name}">
        </label>
    </p>
    <p>
        <label>비밀번호:<br>
        <input type="password" name="password" id="password">
        </label>
    </p>
    <p>
        <label>비밀번호 확인:<br>
        <input type="password" name="confirmPassword" id="confirmPassword">
        </label>
    </p>
    <input type="submit" value="가입 완료">
    </form>
 --%>
</body>
</html>

 

결과

오류 메시지는 메시지 파일 등록된 내용이 아니라 Bean Validation 프로버이더가 제공하는 기본 에러 메시지이다.

 

 

Bean Validation 2.0을 사용하면 추가 애노테이션을 더 사용할 수 있다.

		<dependency>
		<groupId>javax.validation</groupId>
		<artifactId>validation-api</artifactId>
		<version>2.0.1.Final</version>
		</dependency>
		
		<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-validator</artifactId>
		<version>6.0.7.Final</version>
		</dependency>

 

 

 

 

 

자바스크립트 에러 처리 

 

Controller

package controller;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import lombok.extern.slf4j.Slf4j;
import spring.Join;

@Controller
@RequestMapping("/join")
@Slf4j
public class JoinController {
	
	@GetMapping
	public String joinForm(Model model) {
		
		model.addAttribute("join", new Join());
		return"join/register";
	}
	
	@PostMapping
	public String joinExe(@ModelAttribute("join") @Valid Join join, Errors errors) {
		
		if(errors.hasErrors()) {
			
			return"join/register";
		}
		
		log.info("----------->" + join);
		
		return"complete";
	}
	
}

 

 

스프링 설정 ( Controller @Bean 등록 ) 

package config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import controller.JoinController;
import controller.Mycontroller;
import controller.OrderController;
import controller.RegisterController;
import spring.MemberRegisterService;

@Configuration
public class ControllerConfig {

	@Autowired
	private MemberRegisterService memberRegSvc;

	@Bean
	public RegisterController registerController() {
		RegisterController controller = new RegisterController();
		controller.setMemberRegisterService(memberRegSvc);
		return controller;
	}
	
	@Bean
	public Mycontroller mycontroller() {
		return new Mycontroller();
	}
	
	@Bean
	public JoinController joinController() {
		return new JoinController();
	}
	
	@Bean
	public OrderController orderController() {
		return new OrderController();
	}

}

 

 

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<link rel="stylesheet" href="css/register.css">
	<title>회원 가입</title>
</head>
<body>
	<div id="container">
		<h1>회원 가입</h1>
		<form:form method="post" id="register" modelAttribute="join">
			<ul id="user-info">
				<li>
					<label for="userid" class="field">아이디</label>
					<form:input path="userid" placeholder="4~15자리의 영문과 숫자로 입력" required="true" />
					<form:errors path="userid" />
				</li>
				<li>
					<label for="email" class="field">이메일</label>
					<form:input type="email" path="email" required="true" />
					<form:errors path="email" />
				</li>
				<li>
					<label for="userpw1" class="field">비밀번호</label>
					<form:password path="userpw1" placeholder="8자리 이상" required="true" />
					<form:errors path="userpw1" />
				</li>
				<li>
					<label for="userpw2" class="field">비밀번호 확인</label>
					<form:password path="userpw2" placeholder="8자리 이상" required="true" />
					<form:errors path="userpw2" />
				</li>
				<li>
					<label class="field">메일링 수신</label>
					<label class="r"><form:radiobutton
					                      value="true" path="mailing" />예</label>
					<label class="r"><form:radiobutton 
					                     value="false" path="mailing" />아니오</label>
				</li>
			</ul>
			<ul id="buttons">
				<li>
					<button type="submit" class="btn btnBlack">가입하기</button>					
				</li>
				<li>
					<button type="reset" class="btn btnGray">취소</button>
				</li>
			</ul>
		</form:form>
	</div>
	
	<script src="js/register-result.js"></script>
</body>
</html>

 

CSS

#container{
	width:600px;
	margin:0 auto;
}
ul {
	list-style:none;
}
ul li {
	clear:both;
}
.field {
	float:left;
	width:100px;
	font-weight:bold;
	font-size:0.9em;
	line-height: 55px;
	text-align:right;
	margin-right:15px;
}
input[type="text"], input[type="password"], input[type="email"] {
	float:left;
	width:350px;
	height:35px;
	border:1px solid #aaa;
	border-radius:5px;
	padding:5px;
	margin:10px 0;
	float:left;	
}

.r {
	line-height:55px;
}

#buttons > li {
	display:inline-block;
}
button {
	width:250px;
	height:50px;
	margin-right:10px;
	border:1px solid #ccc;
	background:#eee;
	font-size:0.9em;
}

 

JS

		var userId = document.querySelector("#userid");  // ‘아이디’ 필드를 가져와 변수에 저장
		var pw1 = document.querySelector("#userpw1");  // ‘비밀번호’ 필드를 가져와 변수에 저장
		var pw2 = document.querySelector("#userpw2");  // ‘비밀번호 확인’ 필드를 가져와 변수에 저장

		userId.onchange = checkId;
		pw1.onchange = checkPw;
		pw2.onchange = comparePw;

		function checkId() {			
			if (userId.value.length < 4 || userId.value.length > 15) {  // userId 필드 내용의 길이가 4 이하이거나 15 이상일 경우 실행
				alert("4~15자리의 영문과 숫자를 사용하세요.");  // 오류 메시지 출력
				userId.select();    // 다시 입력할 수 있도록 userId 필드 선택
			}
		}

		function checkPw() {			
			if (pw1.value.length < 8) {
        alert("비밀번호는 8자리 이상이어야 합니다.");  // 오류 메시지 표시
        pw1.value = "";  // ‘비밀번호’ 필드 지움
				pw1.focus();  // 비밀번호를 다시 입력할 수 있게 포커싱
			}
		}

		function comparePw() {						
			if(pw1.value != pw2.value) {
				alert("암호가 다릅니다. 다시 입력하세요.");
				pw2.value = "";  // ‘비밀번호 확인’ 필드 지움
				pw2.focus();   // 비밀번호를 다시 입력할 수 있게 포커싱
			}
		}

 

 

 

 

Checkbox => List로 받아서 Pizza 추가 주문건 출력해보기

 

커맨드 객체 ( DTO )

package spring;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@AllArgsConstructor
@Builder
@ToString
@NoArgsConstructor
public class Pizza {
	private String addorder;
	private String total;
	private List<Pizza> plist;
	private List<String> selectedAddOns;
	
}

 

Controller

package controller;

import java.util.ArrayList;
import java.util.List;

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

import lombok.extern.slf4j.Slf4j;
import spring.Pizza;

@Controller
@RequestMapping("/order")
@Slf4j
public class OrderController {
	
	@GetMapping
	public String order(Model model) {
		model.addAttribute("plist", new Pizza());
		

		
		return "order/pizzaOrder";
	}
	
	@PostMapping
	public String result(Model model, @ModelAttribute("plist") Pizza pizza) {
	    List<String> selectedAddOns = new ArrayList<>();
	    
	    
	    if (pizza.getSelectedAddOns() != null) {
	        for (String addOn : pizza.getSelectedAddOns()) {
	            selectedAddOns.add(addOn);
	        }
	    }

	    pizza.setSelectedAddOns(selectedAddOns);
	    model.addAttribute("total", pizza.getTotal());

	    return "order/result";
	}

}

 

스프링 설정 ( Controller @Bean 등록 )

package config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import controller.JoinController;
import controller.Mycontroller;
import controller.OrderController;
import controller.RegisterController;
import spring.MemberRegisterService;

@Configuration
public class ControllerConfig {

	@Autowired
	private MemberRegisterService memberRegSvc;

	@Bean
	public RegisterController registerController() {
		RegisterController controller = new RegisterController();
		controller.setMemberRegisterService(memberRegSvc);
		return controller;
	}
	
	@Bean
	public Mycontroller mycontroller() {
		return new Mycontroller();
	}
	
	@Bean
	public JoinController joinController() {
		return new JoinController();
	}
	
	@Bean
	public OrderController orderController() {
		return new OrderController();
	}

}

 

CSS

#container {
  width:400px;
  margin:0 auto;
}
fieldset {
  margin-bottom:20px;
  border:1px solid #eee;
}
#total {
  border:none;
  font-size:16px;
  font-weight:bold;
}

 

JS

var price = 24000;

var sideMenu = document.querySelectorAll(".checkbx");
var total = document.querySelector("#total");
total.value = price+"원";

for(i=0; i<sideMenu.length; i++){
    sideMenu[i].onclick = function(){
        if(this.checked == true){
            price += parseInt(this.value);
        }
        else{
            price -= parseInt(this.value);
        }
        total.value = price+"원";
    }
}

 

주문 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>연습문제 1</title>
	<link rel="stylesheet" href="css/sol-1.css">
</head>
<body>
	<div id="container">
    <h1>피자 주문</h1>
		<form:form method="post" modelAttribute="plist">
      <fieldset>
        <legend>사이즈</legend>
        <p>Large - 24000 원 </p>
      </fieldset>
      <fieldset>
        <legend>추가 주문 </legend>        
          <label><form:checkbox path="plist[0].addorder" class="checkbx" value="800" label="피클(800원)"/></label>
          <label><form:checkbox path="plist[1].addorder" class="checkbx" value="300" label="칠리 소스(300원)"/></label>
          <label><form:checkbox path="plist[2].addorder" class="checkbx" value="200" label="디핑 소스(200원)"/></label>
          <label><form:checkbox path="plist[3].addorder" class="checkbx" value="4800" label="치즈스틱(4개, 4800원)"/></label>
          <label><form:checkbox path="plist[4].addorder" class="checkbx" value="2400" label="콘 샐러드(2400원)"/></label>      
      </fieldset>
      <fieldset>
        <legend>합계</legend>
        <form:input path="total" class="price" readonly="true" />
        
      </fieldset>
      <input type="submit" />
		</form:form>	
	</div>

	<script src="js/sol-1.js"></script>
</body>
</html>

 

결과 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>주문 결과</title>
</head>
<body>
    <div>
        <h2>주문이 완료되었습니다!</h2>
        <p>총 주문 가격: ${total} </p>

        <h3>선택한 추가 주문 내역:</h3>
        <ul>
            <c:forEach items="${plist.plist}" var="addOn">
                <c:if test="${not empty addOn.addorder}">
                    <li>${addOn.addorder}</li>
                </c:if>
            </c:forEach>
        </ul>
    </div>
</body>
</html>

 

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-08-30 72일차  (0) 2023.08.30
2023-08-29 71일차  (0) 2023.08.30
2023-08-24 68일차  (0) 2023.08.24
2023-08-23 67일차  (0) 2023.08.23
2023-08-22 66일차  (0) 2023.08.23

스프링 MVC 2 : 메시지, 커맨드 객체 검증

 

<spring:message> 태그로 메시지 출력하기 

1. 해당 위치에 문자열을 담은 메시지파일을 작성

 

member.register=회원가입

term=약관
term.agree=약관동의
next.btn=다음단계

member.info=회원정보
email=이메일
name=이름
password=비밀번호
password.confirm=비밀번호 확인
register.btn=가입 완료

register.done=<strong>{0}님 </strong>, 회원 가입을 완료했습니다.

go.main=메인으로 이동

required=필수항목입니다.
bad.email=이메일이 올바르지 않습니다.

duplicate.email=중복된 이메일입니다.

 

글씨가 깨져서 나온다면

Properties에서 밑에 이미지 처럼 UTF-8 설정

 

 

2. 메시지 파일에서 값을 읽어오는 MessageSource 빈을 설정

package config;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

	@Override
	public void configureDefaultServletHandling(
			DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/view/", ".jsp");
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/main").setViewName("main");
	}
	
	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
		ms.setBasenames("message.label");
		ms.setDefaultEncoding("UTF-8");
		return ms;
	}

}

 

3. JSP 코드에서 <spring:message> 태그를 사용해서 메시지를 출력한다.

taglib 임포트 / <spring:message code="사용 할 문자열" /> 사용법

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
	
	<title><spring:message code="member.register" /></title>
</head>
<body>
<h2><spring:message code="term" /></h2>
	<p>약관 내용</p>
	<form action="step2" method="post">
	<label>
		<input type="checkbox" name="agree" value="true">
		<spring:message code="term.agree" />
	</label>
	<input type="submit" value="<spring:message code="next.btn" />" />
	</form>
</body>
</html>

 

 

<spring:message> 태그의 메시지 인자 처리 

	@PostMapping("/register/step2")
	public String handleStep2(
			@RequestParam(value = "agree", defaultValue = "false") Boolean agree,
			Model model) {
		if (!agree) {
			return "register/step1";
		}
		model.addAttribute("registerRequest", new RegisterRequest());
		return "register/step2";
	}

 

arguments 속성을 사용해서 register.done 메시지의 {0}dnlcldp 삽입할 값을 설정

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
    <title><spring:message code="member.register" /></title>
</head>
<body>
   
            <p><spring:message code="register.done"
            	arguments="${registerRequest.name}" />
            </p>
        
    <p><a href="<c:url value='/main'/>">[<spring:message code="go.main" />]</a></p>
</body>
</html>

 

 

 

 

커맨드 객체의 값 검증과 에러 메시지 처리

1. 커맨드 객체를 검증하고 결과를 에러 코드로 저장

스프링 프레임워크에서 지원되는 Validator 인터페이스 구현

 

 

package spring;

public class RegisterRequest {

	private String email;
	private String password;
	private String confirmPassword;
	private String name;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isPasswordEqualToConfirmPassword() {
		return password.equals(confirmPassword);
	}
}

supports 메서드에는 위에 코드처럼 대상이 되는 커맨드 객체 지정 

package controller;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import spring.RegisterRequest;

public class RegisterRequestValidator implements Validator {
	
	private static final String emailRegExp = 
			"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" +
					"[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	private Pattern pattern;
	
	public RegisterRequestValidator() {
		pattern = Pattern.compile(emailRegExp);
	}
	
	@Override
	public boolean supports(Class<?> clazz) {
		     // 대상이 되는 커맨드 객체
		return RegisterRequest.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		RegisterRequest regReq = (RegisterRequest) target;
        // 이메일 프로퍼티 값 유효하지 확인 
		if(regReq.getEmail() == null  || regReq.getEmail().trim().isEmpty()) {
			errors.rejectValue("email", "required");// 에러 코드 추가
		}else {// 정규표현시을 이용해서 이메일이 올바른지 확인
			Matcher matcher = pattern.matcher(regReq.getEmail());
			if(!matcher.matches()) {
				errors.rejectValue("email", "bad");// 에러 코드 추가 
			}
		}
        // ValidationUtils 클래스 활용 
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required");
		ValidationUtils.rejectIfEmpty(errors, "password", "required");
		ValidationUtils.rejectIfEmpty(errors, "confirmPassword", "required");
		if(!regReq.getPassword().isEmpty()) {
			if(!regReq.isPasswordEqualToConfirmPassword()) {
				errors.rejectValue("confirmPassword", "nomatch");
			}
		}
		
		
	}

}

그리고 구현한 validate() 메서드는 두 개의 파라미터를 갖게 되는데 target 파라미터는 검사 대상 객체이고 

errors 파라미터는 검사 결과 에러 코드를 설정하기 위한 객체이다. 순서는

1. 검사 대상 객체의 특정 프로퍼티나 상태가 올바른지 검사

2. 올바르지 않다면 Errors의 rejectValue() 메서드를 이용해서 에러 코드 저장한다.

 

 

 

2. 컨트롤러 설정

커맨드 객체 파라미터 뒤에 Errors 타입 파라미터가 위치하면, 스프링 MVC는 해당 메서드를 호출할 때 커맨드 객체와

연결된 Errors 객체를 생성해서 파라미터로 전달한다.

	@PostMapping("/register/step3")
	public String handleStep3(RegisterRequest regReq, Errors errors) {
		new RegisterRequestValidator().validate(regReq, errors);
		if(errors.hasErrors()) {
			return "register/step2";
		}
		
		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		} catch (DuplicateMemberException ex) {
			
			return "register/step2";
		}
	}

 

 

 

3. 커맨드 객체의 에러 메시지 출력하기

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
    <title><spring:message code="member.register" /></title>
</head>
<body>
    <h2><spring:message code="member.info" /></h2>
    <form:form action="step3" modelAttribute="registerRequest">
    <p>
        <label><spring:message code="email" />:<br>
        <form:input path="email" />
        <form:errors path="email" />
        </label>
    </p>
    <p>
        <label><spring:message code="name" />:<br>
        <form:input path="name" />
        </label>
    </p>
    <p>
        <label><spring:message code="password" />:<br>
        <form:password path="password" />
        </label>
    </p>
    <p>
        <label><spring:message code="password.confirm" />:<br>
        <form:password path="confirmPassword" />
        </label>
    </p>
    <input type="submit" value="<spring:message code="register.btn" />">
    </form:form>

<%--
    <form action="step3" method="post">
    <p>
        <label>이메일:<br>
        <input type="text" name="email" id="email" value="${registerRequest.email}">
        </label>
    </p>
    <p>
        <label>이름:<br>
        <input type="text" name="name" id="name" value="${registerRequest.name}">
        </label>
    </p>
    <p>
        <label>비밀번호:<br>
        <input type="password" name="password" id="password">
        </label>
    </p>
    <p>
        <label>비밀번호 확인:<br>
        <input type="password" name="confirmPassword" id="confirmPassword">
        </label>
    </p>
    <input type="submit" value="가입 완료">
    </form>
 --%>
</body>
</html>

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-08-29 71일차  (0) 2023.08.30
2023-08-25 69일차  (0) 2023.08.25
2023-08-23 67일차  (0) 2023.08.23
2023-08-22 66일차  (0) 2023.08.23
2023-08-21 65일차  (0) 2023.08.21

스프링 MVC Model을 통해 컨트롤러에서 뷰에 데이터 전달하기

 

DTO

package spring;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Data
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString

public class MemberRegistRequest {
	private String[] favoriteOs;
	
	public String[] getFavoriteOs() {
		return favoriteOs;
	}
	
	
	
	
}

 

Controller

	@GetMapping("/regos")
	public String regos1(Model model) {
		model.addAttribute("osList", Arrays.asList("윈도우10", "윈도우11", "맥OS", "리눅스")); 
		model.addAttribute("memberRegisterRequest", new MemberRegistRequest());
		return "regosForm";
	}
	
	@PostMapping("/regos")
	public String regos2(@ModelAttribute("memberRegisterRequest") MemberRegistRequest mrrRequest) {
		log.info("-----------" + mrrRequest);
		
		return "regosResult";
	}

 

JSP ( 입력 Form )

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2><spring:message code="member.register"></spring:message></h2>

<form:form cssStyle="color : red" method="post" modelAttribute="memberRegisterRequest">
<p>
운영체제 선택:<br/>
<label><form:checkboxes items="${osList}" path="favoriteOs" /></label>
</p>
<input type="submit">
</form:form>

</body>
</html>

 

JSP ( 결과 )

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>선택한 운영체제</title>
</head>
<body>
<h2>선택한 운영체제</h2>

<p>선택한 운영체제 목록:</p>
<ul>
    <c:forEach items="${memberRegisterRequest.favoriteOs}" var="os">
        <li>${os}</li>
    </c:forEach>
</ul>

<a href="<c:url value="/regos" />">돌아가기</a>

</body>
</html>

 

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-08-25 69일차  (0) 2023.08.25
2023-08-24 68일차  (0) 2023.08.24
2023-08-22 66일차  (0) 2023.08.23
2023-08-21 65일차  (0) 2023.08.21
2023-08-18 64일차  (0) 2023.08.20

스프링 MVC1 : 요청 매핑, 커맨드 객체, 리다이렉트, 폼 태그, 모델 

 

1. 요청 매핑 애노테이션을 이용한 경로 매핑

@Controller
public class RegisterController {
	
	@RequestMapping("register/step1")
	public String handleStep1() {
		return "register/step1";
	}
	
	@RequestMapping("register/step2")
	public String handleStep2() {
		return "register/step2";
	}
    
    해당 코드를
    
    @Controller
@RequestMapping("/register") 각 메서드에 공통되는 경로
public class RegisterController {
	
	@RequestMapping("/step1") 공통 경로를 제외한 나머지 경로 
	public String handleStep1() {
		return "register/step1";
	}
	
	@RequestMapping("/step2")
	public String handleStep2() {
		return "register/step2";
	}
    
    둘 다 처리하는 경로는 똑같음

 

 

2. GET과 POST 구분: @GetMapping, @PostMapping

해당 코드처럼 작성하면 같은 경로에 대해 GET과 POST방식을 각각 다른 메서드가 처리하도록 설정 가능

	@GetMapping("/register/step2")
	public String handleStep2Get() {
		return "redirect:/register/step1";
	}
	
	
	@PostMapping("/register/step2")
	public String handleStep2(Model model,
			@RequestParam(defaultValue = "false") Boolean agree) {
		
		System.out.println(agree);
		if(!agree) {
			return "/register/step1";
		}
		model.addAttribute("registerRequest", new RegisterRequest());
		return "register/step2";
	}

 

 

스프링 4.3 이전 버전까지는 밑에 처럼 @RequestMapping 애노테이션의 method 속성을 사용해서 HTTP 방식 제한

	@RequestMapping(value = "/register/step1", method = RequestMethod.GET)
	public String handleStep1() {
		return "/register/step1";
	}
    
    	@RequestMapping(value = "/register/step1", method = RequestMethod.POST)
	public String handleStep1() {
		return "/register/step2";
	}

 

 

 

3. 요청 파라미터 접근

밑에 코드에서 value ( 타입 String ) : HTTP 요청 파라미터의 이름을 지정
defaultValue ( 타입 String ) : 요청 파라미터가 값이 없을 때 사용할 문자열 값을 지정, 기본값은 없음  

	@PostMapping("/register/step2")
	public String handleStep2(
			@RequestParam(value = "agree" defaultValue = "false") Boolean agree) {
		
		if(!agree) {
			return "/register/step1"; false면 기존 페이지 유지
		}
		return "register/step2"; true면 step2로 이동
	}

 

JSP

<%@ page contentType="text/html; charset=utf-8" %>
<!DOCTYPE html>
<html>
<head>
	<title>회원가입</title>
</head>
<body>
	<h2>약관</h2>
	<p>약관 내용</p>
	<form action="step2" method="post">
	<label>
		<input type="checkbox" name="agree" value="true"> 약관 동의
	</label>
	<input type="submit" value="다음 단계" />
	</form>
</body>
</html>

 

 

 

4. 리다이렉트 처리

밑에 코드 처럼 /register/step2 해당 경로 url에 입력 시 /register/step1 경로로 이동됨 예 ) 게시물 작성 후 다시 게시물 목록 페이지로 이동하고 싶을 때 사용하면 좋을 꺼 같다.

	@GetMapping("/register/step2")
	public String handleStep2Get() {
		return "redirect:/register/step1";
	}

 

 

 

5. 커맨드 객체를 이용해서 요청 파라미터 사용하기

form 전송 요청을 처리하는 컨트롤러 코드는 각 파라미터 값을 구하기 위해 밑에 이미지 처럼 처리할 순 있지만

요청 파라미터 개수가 증가할 때마다 코드 길이도 길어지는 단점이 있다.

스프링은 이런 불편함을 줄이기 위해 요청 파라미터의 값을 커맨드 객체에 담아주는 기능을 제공한다. 

요청 파라미터의 값을 전달받을 수 있는 세터 메서드를 포함하는 객체를 커맨드 객체로 사용하면 된다. 

 

밑에 코드처럼 작성하면 위에 처럼 작성을 안해줘도 된다. 

@Controller
public class RegisterController {
	

	
	private MemberRegisterService memberRegisterService;
	
	public void setMemberRegisterService(MemberRegisterService memberRegisterService) {
		this.memberRegisterService = memberRegisterService;
	}
	
	@PostMapping("/register/step3")
	public String handleStep3(RegisterRequest regReq) {
		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		}catch(DuplicateMemberException ex) {
			return "register/step2";
		}
		

	}

Config에서 의존 주입도 해야된다.

@Configuration
public class ControllerConfig {
	
	@Autowired
	private MemberRegisterService memberRegisterService;
	
	@Bean
	public RegisterController registerController() {
		RegisterController controller = new RegisterController();
		controller.setMemberRegisterService(memberRegisterService);
		return controller;
	}

 

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입</title>
</head>
<body>
<h2>회원 정보 입력</h2> <!-- 커맨드객체 -->
<form:form action="step3" modelAttribute="registerRequest">
<p>
<label>이메일:<br/> <!-- 이미 있는 이메일이면 다시 폼을 보여줄 때 기존에 입력한 이메일, 이름이 폼에 채워짐 -->
<form:input path="email"/>
</label>
</p>
<p>
<label>이름:<br/>
<form:input path="name"/>
</label>
</p>
<p>
<label>비밀번호:<br/>
<form:password path="password"/>
</label>
<p>
<label>비밀번호 확인:<br/>
<form:password path="confirmPassword"/>
</label>
</p>
<input type="submit" value="가입 완료">
</form:form>
</body>
</html>

 

회원가입 완료 jsp에서 ${registerRequest.name}님 해당 코드로 누구 이름으로 회원가입 했는지 확인 가능하다.

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>회원가입</title>
</head>
<body>
    <p><strong>${registerRequest.name}님</strong> 
        회원 가입을 완료했습니다.</p>
    <p><a href="<c:url value='/main'/>">[첫 화면 이동]</a></p>
</body>
</html>

 

 <p><a href="<c:url value='/main'/>">[첫 화면 이동]</a></p> 해당 코드는 밑에 이미지 처럼 오버라이드하면 해당 프로젝트 실행 시 맨 처음 실행된다. 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-08-24 68일차  (0) 2023.08.24
2023-08-23 67일차  (0) 2023.08.23
2023-08-21 65일차  (0) 2023.08.21
2023-08-18 64일차  (0) 2023.08.20
2023-08-17 63일차  (0) 2023.08.17

+ Recent posts