차근차근/Spring

스프링 빈(bean) 및 서블릿(servlet) 객체 직접 얻기 출처: https://offbyone.tistory.com/144 [쉬고 싶은 개발자]

예쁜꽃이피었으면 2022. 4. 29. 11:11

https://offbyone.tistory.com/144

 

스프링 빈(bean) 및 서블릿(servlet) 객체 직접 얻기

스프링 프레임웍을 사용하여 개발 할때 서비스 객체나 DAO 객체의 빈(bean)을 얻기위해서는 @Autowired 또는 @Resource(name = "빈이름") 같은 annotation 을 사용해서 얻게 됩니다. HttpServletRequest, HttpServ..

offbyone.tistory.com

 

스프링 프레임웍을 사용하여 개발 할때 서비스 객체나 DAO 객체의 빈(bean)을 얻기위해서는 @Autowired 또는 @Resource(name = "빈이름") 같은 annotation 을 사용해서 얻게 됩니다.

 

HttpServletRequest, HttpServletResponse, HttpSession과 같은 서블릿(Servlet)객체를 얻기 위해서는 Controller 메소드의 인자로 지정해서 값을 얻고 필요하면 서비스 객체로 보내기 위해서 서비스 객체의 인터페이스에 인자로 정의해서 사용합니다.

 

이 이외에 유틸리티성 객체에서 데이터베이스에 접근하고자 할때나, 컨트롤러(Controller)나 서비스 객체가 아닌 리스너나, AOP 등에서 서비스객체 또는 DAO 객체를 사용해야 할 경우가 있습니다.

 

이럴때 필요한 빈(Bean)이나 서블릿(Servlet) 객체에 직접 접근 하는 방법입니다. 빈을 직접 얻기 위해서는 ContextLoader로부터 현재의 WebApplicationContext 를 얻은 후 getBean() 메소드로 빈을 얻을 수있습니다.

 

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();

 

서블릿 객체들은 RequestContextHoler로부터 현재의 ServletRequestAttributes 객체를 얻은후, 필요한 객체를 얻을 수 있습니다.

 

ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();

 

다음은 이러한 기능을 모아둔 유틸리티 클래스 입니다. 필요에 따라 수정해서 사용하면 되겠습니다. com.tistory.pentode.util.ContextUtil.java 파일 입니다.

 

package com.tistory.pentode.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class ContextUtil {
	/**
     * 빈을 직접 얻습니다.
     *
     * @param beanName
     * @return
     */
	public static Object getBean(String beanName) {
		WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
		return context.getBean(beanName);
	}

    /**
     * HttpServletReqeust 객체를 직접 얻습니다.
     * @return
     */
	public static HttpServletRequest getRequest() {
		ServletRequestAttributes attr = 
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		return attr.getRequest();
	}

    /**
     * HttpServletResponse 객체를 직접 얻습니다.
     * @return
     */
	public static HttpServletResponse getResponse() {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		return attr.getResponse();
	}

    /**
     * HttpSession 객체를 직접 얻습니다.
     *
     * @param gen 새 세션 생성 여부
     * @return
     */
	public static HttpSession getSession(boolean gen) {
		return ContextUtil.getRequest().getSession(gen);
	}

    /**
     * REQUEST 영역에서 가져오기
     *
     * @param key
     * @return
     */
	public static Object getAttrFromRequest(String key) {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		return attr.getAttribute(key, ServletRequestAttributes.SCOPE_REQUEST);
	}

    /**
     * REQUEST 영역에 객체 저장
     *
     * @param key
     * @param obj
     */
	public static void setAttrToRequest(String key, Object obj) {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		attr.setAttribute(key, obj, ServletRequestAttributes.SCOPE_REQUEST);
	}

    /**
     * SESSION 영역에서 가져오기
     *
     * @param key
     * @return
     */
	public static Object getAttrFromSession(String key) {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		return attr.getAttribute(key, ServletRequestAttributes.SCOPE_SESSION);
	}

    /**
     * Session 영역에 객체 저장
     *
     * @param key
     * @param obj
     */
	public static void setAttrToSession(String key, Object obj) {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		attr.setAttribute(key, obj, ServletRequestAttributes.SCOPE_SESSION);
	}
}

 

사용법

* Object getBean(String beanName) - 빈 이름으로 필요한 빈 객체를 직접 가져옵니다. LoginDAO  @Repository("LoginDAO") 로 빈 이름이 지어져 있다면 다음과 같이 가져올 수 있습니다. LoginDAO loginDao = (LoginDAO)ContextUtil.getBean("LoginDAO");

* HttpServletRequest getRequest() - HttpServletRequest 객체를 직접 얻습니다.

* HttpServletResponse getResponse() - HttpServletResponse 객체를 직접 얻습니다.

* HttpSession getSession(boolean gen) - HttpSession 객체를 직접 얻습니다. 내부적으로 HttpServletRequest 객체를 먼저 구한 다음에 그 객체로부터 HttpSession 객체를 얻습니다.

* Object getAttrFromRequest(String key) - REQUEST 범위에 저장된 객체를 가져옵니다.

* void setAttrToRequest(String key, Object obj) - REQUEST 범위에 객체를 저장합니다.

* Object getAttrFromSession(String key) - SESSION 범위에 저장된 객체를 가져옵니다.

* void setAttrToSession(String key, Object obj) - SESSION 범위에 객체를 저장합니다.

 

지금까지 스프링 빈과 서블릿 객체를 직접 얻어서 사용하는 방법 및 REQUEST, SESSION SCOPE에 객체를 직접 저장하거나, 가져오는 방법을 알아보았습니다.



출처: https://offbyone.tistory.com/144 [쉬고 싶은 개발자]

 

 


[댓글]

web.xml 파일에
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
내용 추가해야 접근이 가능합니다.

출처: https://offbyone.tistory.com/144 [쉬고 싶은 개발자]


안녕하세요. 좋은 지적 감사합니다.

그런데 제가 테스트 했을때는 RequestContextListener 없이 동작을 했습니다.

검색을 좀해보니 리스너가 필요하다는 글이 많이 있네요.

스프링 버전에 관련된것인지 어떤 이유인지 좀 더 확인을 해 봐야 할 것 갈습니다.

이 글의 코드가 동작을 하지 않는다면 리스너를 추가해 보는것도 한가지 방법이되겠네요.

출처: https://offbyone.tistory.com/144 [쉬고 싶은 개발자]


나도 xml에 RequestContextListener없어도 사용가능했음

반응형