Spring-mvcでセッション属性を使用する方法


108

このコードの春のMVCスタイルのアナログを書くのを手伝ってくれませんか?

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

そして、アノテーションによって@ModelAttributeアノテーションが付けられた要素をセッションに追加して、それにアクセスする方法は?

回答:


185

セッションが不要な応答ごとにオブジェクトを削除する場合は、

ユーザーセッション中にオブジェクトを保持する場合は、いくつかの方法があります。

  1. 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プロキシインジェクション:春-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.セッションでModelAttributeを@SessionAttributes( "ShoppingCart")で作成します。

  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(value = "session"、proxyMode = ScopedProxyMode.TARGET_CLASS)
Vadim Kolesnikov

1
最初はシンプルで使いやすいように見えますが、ここではコントローラーセッションをスコープ化することが最悪のオプションです。ただし、将来的にアプリケーションをスケールアウトしたい場合は、おそらくRedisなどの分散セッションストアが必要になるため、問題が発生します(スティッキーセッションを使用しない限り、利便性のために可用性を犠牲にします)。したがって、セッションスコープのBeanは、一般に、単純なシリアライズ可能なPOJOでなければなりません。このようにして、必要に応じてスケールアウトの準備をします。
クリス

RequestContextHolderはどうですか?
user1589188

UserBeanの注入は、sessionスコープが設定されているクラスでBeanを呼び出す場合にのみ機能します。それ以外の場合、セッションが存在しない場合は、user別のクラスにBean を挿入するときにコンテキスト@runtimeにアクティブなセッションがないため、例外がスローされます。!!
Jose Mhlanga

41

使用する @SessionAttributes

ドキュメントを参照してください: @SessionAttributesを使用してリクエスト間のHTTPセッションにモデル属性を保存します

Spring MVCモデルとセッション属性の理解」では、Spring MVCセッションの非常に優れた概要を提供@ModelAttributeし、がセッションに転送される方法/タイミングを説明しています(コントローラーが@SessionAttributes注釈付けられている)。

この記事では@SessionAttributes、Spring 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それはどうだろうか?セッション属性を2番目のコントローラーに追加するのを忘れたようです
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";
}

ps 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>

ログイン後、上記のコードをWebサイトの任意の場所に追加します。セッションが正しく設定されていれば、そこに値が表示されます。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.