[Spring 2.5] SimpleFormController
by 무작정 개발반응형
2022.03.22(61일 차_화요일)
- 스프링(Spring) 2일 차
오늘 스프링의 데이터 전송 방식 및 스프링의 컨트롤러에 대해 정리할 것이다. 양이 많아 나눠서 정리할 건데
여기서는 Spring(스프링)에서의 데이터 전송 방식, SimpleFormController에 대해 정리할 것이다.
예외 처리 (Exception) & SimpleFormController
실행화면
위의 실행 화면은 이번에 만들 예제 화면이다.
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>
반응형
'Back-End > Spring Legacy' 카테고리의 다른 글
[Spring 2.5] 게시판 CRUD 만들기 (0) | 2022.03.23 |
---|---|
[Spring 2.5] Annotation (어노테이션) (0) | 2022.03.23 |
[Spring 2.5] AbstractWizardFormController, MultiTestController (0) | 2022.03.22 |
[Spring 2.5] DI, IoC 란? (0) | 2022.03.21 |
[Spring 2.5] spring2.5 설치&초기 세팅, JRE(JDK) 변경 방법 (0) | 2022.03.21 |
블로그의 정보
무작정 개발
무작정 개발