Sunt confuz în legătură cu modul de utilizare a @SessionAttributes (Programare, Spring, Spring Mvc, Variabile De Sesiune)

zono a intrebat.

Încerc să înțeleg arhitectura Spring MVC. Cu toate acestea, sunt complet confuz în ceea ce privește comportamentul @SessionAttributes.

Vă rugăm să vă uitați la SampleController de mai jos , acesta gestionează metoda post prin clasa SuperForm. De fapt, doar câmpul din clasa SuperForm este doar obligatoriu, așa cum mă așteptam.

Cu toate acestea, după ce am pus @SessionAttributes în Controller, metoda de manipulare este legată ca SubAForm. Poate cineva să-mi explice ce s-a întâmplat în această legătură.

-------------------------------------------------------

@Controller
@SessionAttributes("form")
@RequestMapping(value = "/sample")
public class SampleController {

    @RequestMapping(method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute("form", new SubAForm());
        return "sample/input";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String register(@ModelAttribute("form") SuperForm form, Model model) {
        return "sample/input";
    }
}

-------------------------------------------------------

public class SuperForm {

    private Long superId;

    public Long getSuperId() {
        return superId;
    }

    public void setSuperId(Long superId) {
        this.superId = superId;
    }

}

-------------------------------------------------------

public class SubAForm extends SuperForm {

    private Long subAId;

    public Long getSubAId() {
        return subAId;
    }

    public void setSubAId(Long subAId) {
        this.subAId = subAId;
    }

}

-------------------------------------------------------

<form:form modelAttribute="form" method="post">
    <fieldset>
        <legend>SUPER FIELD</legend>
        <p>
            SUPER ID:<form:input path="superId" />
        </p>
    </fieldset>
    <fieldset>
        <legend>SUB A FIELD</legend>
        <p>
            SUB A ID:<form:input path="subAId" />
        </p>
    </fieldset>
    <p>
        <input type="submit" value="register" />
    </p>
</form:form>

4 răspunsuri
axtavt

Când se procesează POST request, Spring face următoarele:

  • Fără @SessionAttributes: Spring instanțiază o nouă instanță de SuperForm (tipul este dedus din semnătura lui register()), îi populează proprietățile cu valorile din câmpurile formularului și o transmite la instrucțiunea register() metoda.

  • Cu @SessionAttributes: Spring obține o instanță a atributului model din sesiune (unde a fost plasat la procesarea GET din cauza prezenței lui @SessionAttributes), îi actualizează proprietățile cu valorile din câmpurile from și o trece la metoda register() metoda .

Adică, cu @SessionAttributes , register() primește aceeași instanță a obiectului de atribut al modelului care a fost plasat în Model de către getCreateForm().

Comentarii

  • Mulțumesc pentru explicație, sunt puțin confuz cu „Adică, cu @SessionAttribute register( ) obține aceeași instanță a obiectului atribut al modelului care a fost plasat în model prin getCreateForm().”. În ambele cazuri, primești ceea ce a introdus utilizatorul în formular, deci ce vrei să spui prin această propoziție? Vreau să spun că, oricum, primești valorile corecte ale fiecărui câmp, așa că ce rost are să folosești sessionAttribute? Îmi scapă ceva? –  > Por Jack.
  • a fost @SessionAttributes sau @SessionAttribute? :p –  > Por Tahir Hussain Mir.
Ritesh

Adăugând la ceea ce a spus @axtavt: Să presupunem că, în getCreateForm puneți niște valori pentru o listă derulantă (listă sau hartă), sau puneți niște valori în formular pe care le doriți în metoda register, dar nu doriți ca acestea să se afișeze în formular (nici măcar în câmpurile ascunse). Să presupunem acum că a apărut o eroare în register și trebuie să afișați din nou formularul. Pentru a popula valorile din drop down și alte valori de care veți avea nevoie în următoarea postare, va trebui să le repopulați în formular. @SessionAttribute ajută aici, așa cum @axtavt a descris foarte bine mai sus.

Comentarii

  • este @SessionAttribute sau SessionAttributes? :p –  > Por Tahir Hussain Mir.
user1275645
@Controller
@SessionAttributes("test")
public class Controller{
    Customer customer;

    public Controller() {
        super();
        customer = new Customer();
    }

    @ModelAttribute("test")
    public Customer getCustomer() {
       customer.setName("Savac");
       return customer;
    }

    @RequestMapping({"/index"})
    public ModelAndView showMainPage (@ModelAttribute("test") Customer customer, ModelMap model, method = RequestMethod.GET) {
        //in the view you set the name
        return new ModelAndView("index");
    }

    @RequestMapping(value = "customer/{customerID}", method = RequestMethod.GET)
    public ModelAndView viewAdvice(@PathVariable("customerID") int customerID, @ModelAttribute("test") Customer customer, ModelMap model) {
        customer.setName("AnotherName");
        model.addAttribute("test", customer);
        return new ModelAndView("customer");
    }

}

S R Chaitanya

În conformitate cu documentația de referință Spring @ModelAttribute argumentul metodei adnotate este rezolvat după cum urmează:

  • Se recuperează din obiectul model dacă acesta este prezent (în mod normal, se adaugă prin intermediul @ModelAttribute metode adnotate)
  • Recuperarea din sesiunea HTTP prin utilizarea @SessionAttributes.
  • Creați utilizând variabila de cale URI care corespunde cu @ModelAttribute nume prin intermediul unui convertor
  • Se creează cu ajutorul constructorului implicit și se adaugă la Model.

O clasă handler poate fi adnotată cu @SessionAttributes cu o listă de nume ca argumente. Aceasta are rolul de a instrui Spring să persiste (în sesiune) acele elemente de date prezente în datele modelului care corespund numelor specificate în @SessionAttributes adnotare.

Astfel, în clasa SampleController, metoda post @ModelAttribute este rezolvat cu @SessionAttributes field datorită metodei de rezolvare menționate mai sus.