Spring-mvc에서 세션 속성을 사용하는 방법


108

이 코드의 봄 mvc 스타일 아날로그를 작성하는 데 도움을 줄 수 있습니까?

 session.setAttribute("name","value");

그리고 주석으로 @ModelAttribute주석 이 달린 요소 를 세션에 추가하고 액세스하는 방법은 무엇입니까?

답변:


185

세션이 필요하지 않은 각 응답 후 객체를 삭제하려면

사용자 세션 동안 개체를 유지하려면 몇 가지 방법이 있습니다.

  1. 세션에 하나의 속성을 직접 추가하십시오.

    @RequestMapping(method = RequestMethod.GET)
    public String testMestod(HttpServletRequest request){
       ShoppingCart cart = (ShoppingCart)request.getSession().setAttribute("cart",value);
       return "testJsp";
    }

    다음과 같이 컨트롤러에서 가져올 수 있습니다.

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
  2. 컨트롤러 세션 범위 지정

    @Controller
    @Scope("session")
  3. 예를 들어 매번 세션에 있어야하는 사용자 개체가 있습니다.

    @Component
    @Scope("session")
    public class User
     {
        String user;
        /*  setter getter*/
      }

    그런 다음 원하는 각 컨트롤러에 클래스를 삽입하십시오.

       @Autowired
       private User user

    수업을 계속 진행합니다.

  4. AOP 프록시 주입 : spring -xml :

    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
      <bean id="user"    class="com.User" scope="session">     
          <aop:scoped-proxy/>
      </bean>
    </beans>

    그런 다음 원하는 각 컨트롤러에 클래스를 삽입하십시오.

    @Autowired
    private User user

5. HttpSession을 메서드에 전달합니다.

 String index(HttpSession session) {
            session.setAttribute("mySessionAttribute", "someValue");
            return "index";
        }

6. @SessionAttributes ( "ShoppingCart")로 세션에서 ModelAttribute 만들기 :

  public String index (@ModelAttribute("ShoppingCart") ShoppingCart shoppingCart, SessionStatus sessionStatus) {
//Spring V4
//you can modify session status  by sessionStatus.setComplete();
}

또는 전체 컨트롤러 클래스에 모델을 추가 할 수 있습니다.

@Controller
    @SessionAttributes("ShoppingCart")
    @RequestMapping("/req")
    public class MYController {

        @ModelAttribute("ShoppingCart")
        public Visitor getShopCart (....) {
            return new ShoppingCart(....); //get From DB Or Session
        }  
      }

각각 장점과 단점이 있습니다.

@session은 모든 노드에 세션을 복사하는 클라우드 시스템에서 더 많은 메모리를 사용할 수 있으며 직접 방법 (1 및 5)은 복잡한 접근 방식을 사용하므로 단위 테스트에 적합하지 않습니다.

세션 jsp에 액세스하려면

<%=session.getAttribute("ShoppingCart.prop")%>

Jstl에서 :

<c:out value="${sessionScope.ShoppingCart.prop}"/>

Thymeleaf에서 :

<p th:text="${session.ShoppingCart.prop}" th:unless="${session == null}"> . </p>

6
3. 컨트롤러가 싱글 톤 인 경우 세션 범위가있는 삽입 된 구성 요소에 대해 proxyMode = ScopedProxyMode.TARGET_CLASS를 정의해야합니다. @Scope (값 = "세션"프록시 모드 = ScopedProxyMode.TARGET_CLASS)
바딤 콜 레스 니 코프

1
컨트롤러 세션 범위를 지정하는 것은 처음에는 간단하고 사용하기 쉬워 보이지만 여기서는 최악의 옵션입니다. 그러나 나중에 애플리케이션을 확장하려는 경우 Redis와 같은 분산 세션 저장소가 필요할 수 있으므로 문제가 발생할 수 있습니다 (고정 세션을 사용하지 않는 한 편의를 위해 가용성을 희생 함). 따라서 세션 범위 빈은 일반적으로 멍청한 직렬화 가능한 POJO 여야합니다. 이렇게하면 필요할 때 확장 할 수 있습니다.
chris

RequestContextHolder는 어떻습니까?
user1589188

User빈을 주입하는 것은 클래스에서 빈을 호출하는 경우에만 작동하며 session, 그렇지 않으면 세션이 존재하지 않으면 user다른 클래스에 빈 을 주입 할 때 @runtime 컨텍스트에 활성 세션이 없기 때문에 예외가 발생합니다. !!
Jose Mhlanga

41

사용하다 @SessionAttributes

문서 참조 : @SessionAttributes를 사용하여 요청 사이의 HTTP 세션에 모델 속성 저장

" Spring MVC 모델 및 세션 속성 이해 "는 또한 Spring MVC 세션에 대한 매우 좋은 개요를 제공하고 @ModelAttributes가 세션으로 전송되는 방법 /시기를 설명합니다 (컨트롤러에 @SessionAttributes주석 이 달린 경우).

이 기사는 또한 @SessionAttributesSpring MVC가 뷰에 구애받지 않는 데 도움이되므로 HttpSession에서 직접 속성을 설정하는 대신 모델 에서 사용하는 것이 더 낫다고 설명합니다 .


컨트롤러간에 객체를 전송하기 위해 sessionAttributes를 어떻게 활용할 수 있습니까?
larrytech

27

SessionAttribute주석은 요청 객체에서 세션을 가져오고 속성을 설정하는 대신 가장 간단하고 간단합니다. 모든 객체는 컨트롤러의 모델에 추가 될 수 있으며 이름이 @SessionAttributes주석 의 인수와 일치하면 세션에 저장됩니다 . 예를 들어 아래 personObj에서 세션에서 사용할 수 있습니다.

@Controller
@SessionAttributes("personObj")
public class PersonController {

    @RequestMapping(value="/person-form")
    public ModelAndView personPage() {
        return new ModelAndView("person-page", "person-entity", new Person());
    }

    @RequestMapping(value="/process-person")
    public ModelAndView processPerson(@ModelAttribute Person person) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("person-result-page");

        modelAndView.addObject("pers", person);
        modelAndView.addObject("personObj", person);

        return modelAndView;
    }

}

세션은 동일한 컨트롤러 인스턴스 내의 요청에 대해서만 작동합니다. 제어권을 다른 컨트롤러로 보내야하는 경우이 세션이 삭제되고 필요한 경우 새 세션이 생성됩니다.
larrytech

1
@larrytech 어떻게 될 수 있습니까? 두 번째 컨트롤러에 SessionAttributes를 추가하는 것을 잊은 것 같습니다
Yura

19

아래 주석이 달린 코드는 "값"을 "이름"으로 설정합니다.

@RequestMapping("/testing")
@Controller
public class TestController {
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
    request.getSession().setAttribute("name", "value");
    return "testJsp";
  }
}

JSP에서 동일하게 액세스하려면 ${sessionScope.name}.

찾는 @ModelAttribute이 참조 링크를


4

그렇게하는 것이 가장 쉽고 짧지 않습니까? 나는 그것을 알고 방금 테스트했습니다-여기서 완벽하게 작동합니다.

@GetMapping
public String hello(HttpSession session) {
    session.setAttribute("name","value");
    return "hello";
}

추신 여기에 " Spring-mvc에서 세션 속성을 사용하는 방법 "에 대한 답을 찾기 위해 왔지만 내 코드에서 작성한 가장 분명한 내용을 보지 않고 너무 많이 읽었습니다. 나는 그것을 보지 못했기 때문에 그것이 잘못되었다고 생각했지만 그렇지 않았습니다. 그래서 그 지식을 주요 질문에 대한 가장 쉬운 해결책과 공유합시다.


1
네가 옳아 ! 컨트롤러 메서드 (GET / POST 요청)에서 선언 할 때 필요한 모든 Http 개체에 직접 액세스 할 수 있기 때문에 제가 생각했던 것입니다
Shessuky

1

이 시도...

@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {

    @ModelAttribute("types")

    public Collection<PetType> populatePetTypes() {
        return this.clinic.getPetTypes();
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
        new PetValidator().validate(pet, result);
        if (result.hasErrors()) {
            return "petForm";
        }else {
            this.clinic.storePet(pet);
            status.setComplete();
            return "redirect:owner.do?ownerId="
                + pet.getOwner().getId();
        }
    }
}

0

로그인 (부트 스트랩 모달)을 시도 할 때 @sessionattributes 주석을 사용했습니다. 그러나 문제는 뷰가 리디렉션 ( "redirect : / home") 일 때 세션에 입력 한 값이 URL에 표시된다는 것입니다. 일부 인터넷 소스는 http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting 을 따르도록 제안 했지만 대신 HttpSession을 사용했습니다. 이 세션은 브라우저를 닫을 때까지 유지됩니다. 다음은 샘플 코드입니다.

        @RequestMapping(value = "/login")
        @ResponseBody
        public BooleanResponse login(HttpSession session,HttpServletRequest request){
            //HttpServletRequest used to take data to the controller
            String username = request.getParameter("username");
            String password = request.getParameter("password");

           //Here you set your values to the session
           session.setAttribute("username", username);
           session.setAttribute("email", email);

          //your code goes here
}

뷰 측에서 특정 사항을 변경하지 않습니다.

<c:out value="${username}"></c:out>
<c:out value="${email}"></c:out>

로그인 후 웹 사이트의 어느 곳에 나 위의 코드를 추가하십시오. 세션이 올바르게 설정되면 값이 표시됩니다. jstl 태그 및 El- 표현식을 올바르게 추가했는지 확인하십시오 (여기에 jstl 태그를 설정하는 링크가 있습니다. https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project- 올바르게 / )


0

이 방법은 사용하기 매우 간단합니다.

HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getNativeRequest();

                                                            request.getSession().setAttribute("errorMsg", "your massage");

jsp에서 한 번 사용한 다음 제거

<c:remove var="errorMsg" scope="session"/>      

0

Spring 4 Web MVC에서. 컨트롤러 수준에서 사용 @SessionAttribute하는 방법으로 사용할 수 있습니다.@SessionAttributes

@Controller
@SessionAttributes("SessionKey")
public class OrderController extends BaseController {

    GetMapping("/showOrder")
    public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
     // method body
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.