무작정 개발.Vlog

[Spring 2.5] SimpleFormController

by 무작정 개발
반응형
2022.03.22(61일 차_화요일)
 - 스프링(Spring) 2일 차

 

 

오늘 스프링의 데이터 전송 방식 및 스프링의 컨트롤러에 대해 정리할 것이다. 양이 많아 나눠서 정리할 건데

여기서는 Spring(스프링)에서의 데이터 전송 방식, SimpleFormController에 대해 정리할 것이다.

 

예외 처리 (Exception) & SimpleFormController

 

실행화면

login.jsp 실행화면
login.jsp 실행화면
login_ok.jsp 실행 화면
login_ok.jsp 실행 화면

위의 실행 화면은 이번에 만들 예제 화면이다.

 

 

1. LoginCommand 클래스 생성

  • Command 클래스는 스프링에서 DTO 역할을 하는 클래스
package com.test1;
//Command는 스프링의 DTO
public class LoginCommand { // DTO
	
	private String userId;
	private String userPwd;
	private String loginType; //회원등급을 구분하는 파라미터
    
    // getter/setter 생성

 

 

2. 예외 처리

  • 예외 처리 시 필요한 파일 : UserException클래스, Authenticator인터페이스, LoginAuthenticatorImpl 클래스

(1) - UserException.java 생성

package com.test1;

//예외처리 필요한 파일
public class UserException extends Exception {

	private static final long serialVersionUID = 1L;
	
	//에러를 처리할때 애한테 보낸다.
	// - 생성자
	public UserException(String str) {
		super(str);//super는 Exception이다.
	}

}

 

(2) - Authenticator.java (인터페이스)

package com.test1;

public interface Authenticator {
	
	//예외처리를 UserException한테 맡긴다.
	public void authen(String userId,String userPwd) 
		throws UserException;
			
}

 

(3) - LoginAuthenticator.java 생성

  • Authenticator 인터페이스를 구현한 클래스
package com.test1;
//Authenticator인터페이스를 구현한 클래스
public class LoginAuthenticatorImpl implements Authenticator {

	@Override
	public void authen(String userId, String userPwd)//애를 호출했을 때
			throws UserException {
		
		if(!userId.equals("suzi") || !userPwd.equals("123")) {
			//suzi, 123이 아니면 예외를 발생시킨다.
			throw new UserException("invalid id: " + userId);
		}
		
	}

}

 

 

3. LoginController 클래스 생성

  • SimpleFormController를 상속(extends) 받음
  • SimpleFormController : Form을 출력하고 Form에 입력한 데이터를 처리할 때 사용된다.
  • onSubmit() 메서드 : submit 버튼을 클릭하면 자동으로 실행하는 메서드
  • referenceData() 메서드 : 특정 데이터를 입력창에 보낼 때 사용
package com.test1;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

// SimpleFormController : 사용자가 폼에서 버튼클릭시 submit이 실행되는데 자동으로 onSubmit() 자동호출
// 창을 띄우기 전에 준비 작업 정보를 referenceData 를 가지고 창에 띄어진다. 
// 그리고 ok버튼누르면 submit실행이 되면 onSubmit이 실행됨
public class LoginController extends SimpleFormController {
	
	private Authenticator authenticator;
	
	// 의존성 주입(DI) - setter만 만든다.
	// 클래스 생성 시 자동으로 실행
	public void setAuthenticator(Authenticator authenticator) {
		this.authenticator = authenticator;
	}
	
	//2. 로그인버튼을 누르면 submit이 실행되서 이 메서드를 실행한다.
	//   실행되면서 DTO가 command로 넘어와서 여기서 받아준다.
	//   그리고 _ok에 있는 {message}로 던져준다.
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request, 
			HttpServletResponse response, Object command, //입력한 데이터는 command로 들어온다.
			BindException errors) throws Exception {
		
		// ok버튼을 누르면 onSubmit이 자동으로 실행되며 , 데이터는 Object command 에 넘어온다.
		LoginCommand login = (LoginCommand)command;
		
		try {
			
			//넘어온 ID,PWD를 넘긴다.
			authenticator.authen(login.getUserId(), login.getUserPwd());
			
			String message = "id: " + login.getUserId();
			message += ", pwd: " + login.getUserPwd();
			message += ", type: " + login.getLoginType();
			
			request.setAttribute("message", message);
			
			// test1폴더에 login_ok한테 넘긴다.
			return new ModelAndView("test1/login_ok");
			
		} catch (Exception e) {
			// 로그인버튼을 누르면 화면이 바뀌므로 창을 다시 보여주게 해야한다.
			return showForm(request, response, errors);// 에러메시지를 가지고 입력창을 다시 띄운다.(다시 로그인을 하게끔)
		}
		
	}
	
	
	//1. 여기에 코딩한 부분이 login.jsp가 뜰때 로그인 타입에 데이터를 띄워준다. 
	//   그래서 여기에는 타입부분에 들어갈 내용을 코딩 ( referenceData가 먼저 실행된다)
	@Override
	protected Map<String, List<String>> referenceData(HttpServletRequest request) throws Exception {
		
		List<String> loginTypes = new ArrayList<>();
		loginTypes.add("일반회원");
		loginTypes.add("기업회원");
		loginTypes.add("특별회원");
		
		// 추가된 리스트는 맵에 추가
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		map.put("loginType", loginTypes);// loginType이라는 이름으로 넘긴다.
			
		return map;	
	}
	
}

 

 

4. View 생성 (JSP페이지 - login.jsp, login_ok.jsp 생성)

 

 

(1) - login.jsp - (로그인 시 필요한 데이터 입력)

  • Type를 submit으로 설정해야 컨트롤러의 onsubmit 메서드가 실행된다.
  • 로그인 타입을 referenceData 메서드를 통해 전달받아서 출력하기에 <c:each> 태그 사용
  • 주의 - items의 변수명과 보내는 데이터명이 같아야 한다.
<body>
<form action="<%=cp%>/test1/login.action" method="post">

아이디: <input type="text" name="userId"/><br/>
패스워드: <input type="password" name="userPwd"/><br/>
로그인 타입:
<!-- LoginController.java의 referenceData 데이터를 가져온다. -->
<select name="loginType">
	<c:forEach var="type" items="${loginType }">
		<option value="${type }">${type }</option>
	</c:forEach>
</select>
<br/>
<!-- LoginController.java에서 onSubmit을 사용하기 때문에 type을 submit으로 한다. -->
<input type="submit" value="로그인"/>

</form>
</body>

 

(2) - login_ok.jsp - (로그인 성공 시 생성한 message 출력)

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
${message }
</body>

</html>

 

 

5. dispatcher-servlet.xml 작성

  • 여기서 2가지 작업을 해줘야 한다.

(1) pro의 key가 실제 물리적인 주소와 같으면 formView는 생략 가능

<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="order" value="1"/> <!-- Spring은 어노테이션으로 쓸수있는데  수동적인 주소 어떤걸 우선할것인가 , value = 1  얘를 먼저 실행해라 -->
	<property name="alwaysUseFullPath" value="true"/>
	<property name="mappings">
		<props>
        	<!-- login.action 으로 이동하면 bean name=loginController 찾는다.  -->
			<prop key = "/test1/login.action">loginController</prop> 
		</props>
	</property>
</bean>

 

 

(2) <bean name="authenticator" class="com.test 1.LoginAuthenticatorImpl"/> 

  • authenticator 의존성 주입에 값을 넘겨주기 위해 객체 생성
  • 여기서 authenticator 값을 넘겨주기 시작

(3) 객체 생성

<property name="commandClass" value="com.test 1.LoginCommand"/>
<property name="commandName" value="loginCommand"></property>

  • LoginCommand.java를 loginCommand라는 이름으로 객체 생성
  • commandClass의 value값에 있는 클래스를 commandName의 value값으로 객체 생성
  • LoginCommand loginCommand = new LoginCommand();와 같다.
  • 항상 2개가 짝으로 같이 다님
  • formView : 명시적으로 다음 화면을 띄우라고 지정해주는 것
<!-- 예제1 (com.test1)-->
<!-- authenticator의 setter에게 ref="authenticator-ref"의 객체를 전달해줘서 bean(객체) 생성 / (제어의 역전) -->
<!-- property name:setter에 ref:bean으로 객체 생성한걸 넣어주면서 의존성 주입 -->
<bean name="authenticator" class="com.test1.LoginAuthenticatorImpl"/>  
<bean name="loginController" class="com.test1.LoginController"> <!-- LoginController 에 setAuthenticator(Authenticator authenticator) 에 의존성주입을 한다. -->
	<property name="authenticator" ref="authenticator"></property> <!--(의존성주입) authenticator 객체를 생성해서 LoginController authenticator를 setter로 저장한다. -->
	
	<!-- com.test에 LoginController에 객체생성해준것과 같음. xml에서의 문법 -->
	<!-- com.test1.LoginController가 사용해야 하므로 Command 객체 생성 -->
	<property name="commandClass" value="com.test1.LoginCommand"/> <!-- LoginCommand 클래스를 loginCommand라는 이름으로 객체 생성 -->
	<property name="commandName" value="loginCommand"></property> <!-- LoginCommand의 value값에 있는 클래스를  commandName의 value값으로 객체 생성 -->
																  <!-- LoginCommand loginCommand = new LoginCommand();와 동일 -->		
	<!-- formView속성으로 정의되어 있는 페이지로 이동 -->
	<property name="formView" value="test1/login"/><!-- 처음실행시 login.jsp띄우고 에러발생시 login.jsp가 떠야한다. -->
</bean>

 

 

반응형

블로그의 정보

무작정 개발

무작정 개발

활동하기