스프링

 

@Autowired를 이용한 의존 자동 주입

자동 주입 기능을 사용하면 스프링이 알아서 의존 객체를 찾아서 주입한다. 

 

1. 필드에 @Autowired

package spring;

import org.springframework.beans.factory.annotation.Autowired;

public class ChangePasswordService {
	
	@Autowired  // 자동 주입 설정
	private MemberDao memberDao;

	public void changePassword(String email, String oldPwd, String newPwd) {
		Member member = memberDao.selectByEmail(email);
		if (member == null)
			throw new MemberNotFoundException();

		member.changePassword(oldPwd, newPwd);

		memberDao.update(member);
	}

	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}

}

해당 클래스 필드에 @Autowired 애노테이션이 붙어 있으면 스프링이 해당 타입의 빈 객체를 찾아서
필드에 할당한다.
	@Bean
	public ChangePasswordService changePwdSvc() {
		
		ChangePasswordService pwdSvc = new ChangePasswordService();
//		pwdSvc.setMemberDao(memberDao()); // 의존 객체 명시 하지 않아도 스프링이 알아서 자동 주입
		return pwdSvc;
	}
    
    주석 처리 한 부분처럼 @Bean에 의존을 주입을 안해도 된다.

 

 

2. 메서드에 @Autowired

package spring;

import org.springframework.beans.factory.annotation.Autowired;

public class MemberInfoPrinter {
	
	private MemberDao memDao;
	private MemberPrinter printer;

	public void printMemberInfo(String email) {
		Member member = memDao.selectByEmail(email);
		if (member == null) {
			System.out.println("데이터 없음\n");
			return;
		}
		printer.print(member);
		System.out.println();
	}
	@Autowired
	public void setMemberDao(MemberDao memberDao) {
		this.memDao = memberDao;
	}
	@Autowired
	public void setPrinter(MemberPrinter printer) {
		this.printer = printer;
	}

}

빈 객체의 메서드에 @Autowired을 붙이면 스프링은 해당 메서드를 호출한다 
이 때 메서드 파라미터 타입에 해당하는 빈 객체를 찾아 인자로 주입한다.

 

	@Bean
	public MemberPrinter memberPrinter() {
		return new MemberPrinter();
	}
    
    	@Bean
	public MemberInfoPrinter infoPrinter() {
		MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
		return infoPrinter;
	}

위에 이미지는 @Autowired 애노테이션을 적용했을 때 주입이 어떻게 연결되는 보여주는 이미지

ChangePasswordService의 memberDao 필드 타입은 MemberDao이므로 일치하는 타입을 가진 memberDao 빈이

주입된다.  비슷하게 MemberInfoPrinter의 setMemberDao()메서드의 memberDao 파라미터 타입이 MemberDao 이므로 setMemberDao() 메서드에 일치하는 타입을 가진 memberDao 빈이 주입 된다. 

 

 

3. MemberRegisterService 클래스에 필드에 @Autowired추가 인자 없는 기본 생성자 추가 

public class MemberRegisterService {
	
	@Autowired
	private MemberDao memberDao;
	
	public MemberRegisterService() { // 인자 없는 기본 생성자 추가
		
	}
	
	public MemberRegisterService(MemberDao memberDao) {
		this.memberDao = memberDao;
	}

 

3. MemberListPrinter 클래스에 메서드에 @Autowired추가 인자 없는 기본 생성자 추가 

package spring;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class MemberListPrinter {

	private MemberDao memberDao;
	private MemberPrinter printer;
	
	public MemberListPrinter() {
		
	}
	
	
	public MemberListPrinter(MemberDao memberDao, MemberPrinter printer) {
		this.memberDao = memberDao;
		this.printer = printer;
	}

	public void printAll() {
		Collection<Member> members = memberDao.selectAll();
		members.forEach(m -> printer.print(m));
	}
	
	@Autowired
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	@Autowired
	public void setMemberPrinter(MemberPrinter printer) {
		this.printer = printer;
	}
}

 

기본 생성자 추가하는 이유는 AppCtx 클래스에서 기본 생성자를 이용해서 객체를 생성하기 위함

 

 

스프링 빈으로 생성할 모든 클래스에 @Autowired 애노테이션을 적용 / 설정 클래스 의존 주입 코드 제거 

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import spring.ChangePasswordService;
import spring.MemberDao;
import spring.MemberInfoPrinter;
import spring.MemberListPrinter;
import spring.MemberPrinter;
import spring.MemberRegisterService;
import spring.MemberSummaryPrinter;
import spring.VersionPrinter;

@Configuration
public class AppCtx {

	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		return new MemberRegisterService();
	}
	
	@Bean
	public ChangePasswordService changePwdSvc() {
		
		return new ChangePasswordService();
	}
	
	@Bean
	
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
	
//	@Bean
//	public MemberPrinter memberPrinter2() {
//		return new MemberPrinter();
//	}
	
	@Bean
	
	public MemberSummaryPrinter memberPrinter2() {
		return new MemberSummaryPrinter();
	}
	
	@Bean
	public MemberListPrinter listPrinter() {
		return new MemberListPrinter();
	}
	
	@Bean
	public MemberInfoPrinter infoPrinter() {
		MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
		return infoPrinter;
	}
	
	@Bean
	public VersionPrinter versionPrinter() {
		VersionPrinter versionPrinter = new VersionPrinter();
		versionPrinter.setMajorVersion(5);
		versionPrinter.setMinorVersion(0);
		return versionPrinter;
	}
}

 

 

 

@Qualifier 애노테이션을 이용한 의존 객체 선택

자동 주입 가능한 빈이 두 개 이상이면 자동 주입할 빈을 지정할 수 있는 방법이 해당 애노테이션

	@Bean
	@Qualifier("printer")
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
	
	@Bean
	public MemberPrinter memberPrinter2() {
		return new MemberPrinter();
	}

해당 빈의 한정 값으로 "printer" 지정

 

public class MemberListPrinter {

	private MemberDao memberDao;
	private MemberPrinter printer;
	
	public MemberListPrinter() {
		
	}
	
	
	public MemberListPrinter(MemberDao memberDao, MemberPrinter printer) {
		this.memberDao = memberDao;
		this.printer = printer;
	}

	public void printAll() {
		Collection<Member> members = memberDao.selectAll();
		members.forEach(m -> printer.print(m));
	}
	
	@Autowired
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	@Autowired
	@Qualifier("printer")
	public void setMemberPrinter(MemberPrinter printer) {
		this.printer = printer;
	}
}

위에 지정한 한정 값은 @Autowired 애노테이션에서 자동 주입할 빈을 한정할 때 사용한다. ( 주입 대상 지정 ) 

 

 

 

 

 

상위 / 하위 타입 관계와 자동 주입

package spring;

public class MemberSummaryPrinter extends MemberPrinter {

	@Override
	public void print(Member member) {
		System.out.printf(
				"회원 정보: 이메일=%s, 이름=%s\n", 
				member.getEmail(), member.getName());
	}

}

해당 클래스는 MemberPrinter 클래스를 상속한 클래스 이다. 

해당 클래스는 MemberPrinter에 상속되어 있기 때문에 memberprinter1과 memberprinter2 타입 빈중에서 어떤 빈을주입해야 할지 알 수 없기 때문에 에러가 발생 

	@Bean
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}

	@Bean
	public MemberSummaryPrinter memberPrinter2() {
		return new MemberSummaryPrinter();
	}

 

자동 주입이 되므로 어떤 빈을 주입할지 결정해야 한다. 

 

	@Bean
	@Qualifier("printer")
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
    
    	@Bean
	@Qualifier("summaryPrinter")
	public MemberSummaryPrinter memberPrinter2() {
		return new MemberSummaryPrinter();
	}

 

public class MemberListPrinter {

	private MemberDao memberDao;
	private MemberPrinter printer;
	
	public MemberListPrinter() {
		
	}
	
	
	public MemberListPrinter(MemberDao memberDao, MemberPrinter printer) {
		this.memberDao = memberDao;
		this.printer = printer;
	}

	public void printAll() {
		Collection<Member> members = memberDao.selectAll();
		members.forEach(m -> printer.print(m));
	}
	
	@Autowired
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	@Autowired
	@Qualifier("summaryPrinter")
	public void setMemberPrinter(MemberPrinter printer) {
		this.printer = printer;
	}
}

MemberListPrinter 클래스에 자동 주입할 MemberPrinter 타입 빈은 두 가지 방법으로 처리 하도록 설정

둘 중 하나 @Qualifiter 애노테이션으로 주입 대상 선택 가능하다.

 

 

 

JSP ( Cookie ( 쿠키 ) ) 

기본 개념 코드 

 

쿠키 생성하기

response 기본 객체의 addCookie()메서드를 사용하여 쿠키 추가 웹 브라우저에 쿠키 정보를 추가로 전송

getName() 리턴 타입 String : 쿠키의 이름을 구한다.

getValue() 리턴 타입 String : 쿠키의 값을 구한다. 

setMaxAge(int expiry) 리턴 타입 void : 쿠키의 유효 시간을 초 단위로 지정 / 음수를 입력할 경우 웹 브라우저를 닫을 때 쿠키가 함께 삭제

<%@page import="java.net.URLEncoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
Cookie cookie = new Cookie("name1", "abcd1");
response.addCookie(cookie);
cookie = new Cookie("name2", "abcd2");
response.addCookie(cookie);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%= cookie.getName() %> = <%=cookie.getValue() %><br/>
<%= cookie.getName() %> = <%=cookie.getValue() %>
</body>
</html>

쿠키 값 읽어오기

쿠키를 생성하고 그 다음부터는 생성한 쿠키를 사용할 수있다. 웹 브라우저는 요청 헤더에 쿠키를

저장해서 보내며, JSP 다음의 코드를 사용해서 쿠키 값을 읽어올 수 있다. 

Cookie[] cookies = request.getCookies();

request.getCookies() 메서드는 Cookie 배여를 리턴하며, 읽어올 쿠키가 존재하지 않을 경우 null을 리턴

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();

if (cookies != null && cookies.length > 0) {
	
	for (int i=0; i < cookies.length; i++) {
		out.println("<br/>");
		out.println(cookies[i].getName()+"=");
		out.println(cookies[i].getValue());
	}
}
%>
</body>
</html>

 

 

쿠키 값 변경 

값을 변경하려는 쿠키가 존재하지 않는다면 새롭게 쿠키를 생성하게 된다.

쿠키가 존재하는 확인 후 값을 변경하는게 좋다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
	for (int i=0; i < cookies.length; i++) {
		if (cookies[i].getName().equals("name1")) {
			Cookie cookie1 = new Cookie("name1", "zxcv");
			response.addCookie(cookie1);
		}
	}
}
%>
</body>
</html>

 

쿠키 삭제하기

쿠키를 삭제하는 기능을 별도로 제공하지는 않지만, 유효 시간을 0으로 지정해준 후 응답 헤더에 추가하면 삭제하게 된다

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
	for (int i=0; i < cookies.length; i++) {
		if (cookies[i].getName().equals("name1")) {
			Cookie cookie1 = new Cookie("name1", "");
			cookie1.setMaxAge(0);
			response.addCookie(cookie1);
		}
	}
}
%>
</body>
</html>

 

 


 

 

 

유틸 코드 사용해서 생성, 읽기

 

유틸

package util;


import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; 

public class Cookies {
	
	private Map<String, Cookie> cookieMap = 
			new java.util.HashMap<String, Cookie>();
	
	public Cookies(HttpServletRequest request) {
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (int i = 0 ; i < cookies.length ; i++) {
				cookieMap.put(cookies[i].getName(), cookies[i]);
			}
		}
	}

	public Cookie getCookie(String name) {
		return cookieMap.get(name);
	}
	
	public String getValue(String name) throws IOException {
		Cookie cookie = cookieMap.get(name);
		if (cookie == null) {
			return null;
		}
		return URLDecoder.decode(cookie.getValue(), "utf-8");
	}

	public boolean exists(String name) {
		return cookieMap.get(name) != null;
	}

	public static Cookie createCookie(String name, String value)
	throws IOException {
		return new Cookie(name, URLEncoder.encode(value, "utf-8"));
	}

	public static Cookie createCookie(String name, String value, String path, 
		int maxAge) throws IOException {
		Cookie cookie = new Cookie(name, URLEncoder.encode(value, "utf-8"));
		cookie.setPath(path);
		cookie.setMaxAge(maxAge);
		return cookie;
	}
	
	public static Cookie createCookie(String name, String value, String domain,
			String path, int maxAge) throws IOException {
		Cookie cookie = new Cookie(name, URLEncoder.encode(value, "utf-8"));
		cookie.setDomain(domain);
		cookie.setPath(path);
		cookie.setMaxAge(maxAge);
		return cookie;
	}

}

 

 

생성

<%@page import="util.Cookies"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
response.addCookie(Cookies.createCookie("name", "가나다"));
response.addCookie(Cookies.createCookie("id", "abc", "/", 60 ));
%>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

 

읽기 ( view )

<%@page import="util.Cookies"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
Cookies cookies = new Cookies(request);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<% if (cookies.exists("id")){ %>
<%=cookies.getValue("id")%><br/>
<%} %>

<% if (cookies.exists("name")){ %>
<%=cookies.getValue("name")%><br/>
<%} %>
</body>
</html>

 

Cookie 로그인 예제 

 

loginForm.jsp

<%@ page contentType = "text/html; charset=utf-8" %>
<html>
<head><title>로그인폼</title></head>
<body>

<form action="<%= request.getContextPath() %>/member/login.jsp"
      method="post">
아이디 <input type="text" name="id" size="10">
암호 <input type="password" name="password" size="10">
<input type="submit" value="로그인">
</form>

</body>
</html>

login.jsp

로그인 아이디, 비밀번호 똑같은지 체크

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page import = "util.Cookies" %>
<%
	String id = request.getParameter("id");
	String password = request.getParameter("password");
	
	if (id.equals(password)) {
		// ID와 암호가 같으면 로그인에 성공한 것으로 판단.
		response.addCookie(
			Cookies.createCookie("AUTH", id, "/", -1)
		);
%>
<html>
<head><title>로그인성공</title></head>
<body>

로그인에 성공했습니다.

</body>
</html>
<%
	} else { // 로그인 실패시
%>
<script>
alert("로그인에 실패하였습니다.");
history.go(-1);
</script>
<%
	}
%>

loginCheck.jsp

로그인 상태 인지 확인

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page import = "util.Cookies" %>
<%
	Cookies cookies = new Cookies(request);
%>
<html>
<head><title>로그인여부 검사</title></head>
<body>

<%
	if (cookies.exists("AUTH")) {
%>
아이디 "<%= cookies.getValue("AUTH") %>"로 로그인 한 상태
<%
	} else {
%>
로그인하지 않은 상태
<%
	}
%>
</body>
</html>

logout.jsp

로그아웃 jsp 실행 시 쿠키 삭제되서 로그아웃 처리 됨 

 

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

2023-08-02 54일차  (0) 2023.08.02
2023-08-01 53일차  (0) 2023.08.01
2023-07-28 51일차  (0) 2023.07.28
2023-07-27 50일차  (0) 2023.07.27
2023-07-26 49일차  (0) 2023.07.26

+ Recent posts