0

here and there I was trying to keep form data present when a user is traversing an app and as well when he returns to a form. Form is using a binding list (Dto.List), and user is capable to add entries to it so there might be some work there, but not so much that the form must be persisted every time a new entry is added to the list (in a form).

Trivial controller's method isn't achieving this, because this creates new Dto every time user leaves that form and returns back:

// Start with a brand new Dto
@GetMapping("/new")
public ModelAndView newDto() { return new ModelAndView( "form", "dto", new Dto() ); }

Keeping following in mind: https://rules.sonarsource.com/java/RSPEC-3750

I came up with the following implementation, but I am questioning it if there is more elegant one?

add custom .defaultSuccessUrl

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
.formLogin().loginPage("/login").defaultSuccessUrl( "/afterLogin", true )

add /afterLogin endpoint and adjust method to not create new object every time user returns

@Controller
public class DtoController {

  // Per user Dto
  Dto dto;

  // Initialize Dto
  @GetMapping("/afterLogin")
  public String afterLogin() {
    dto = new Dto();
    return "redirect:/";
  }

  // Never Start with a brand-new Dto until user hits Cancel button
  @GetMapping("/new")
  public ModelAndView keepDto() { return new ModelAndView( "form", "dto", dto ); }


  // Add another Entry to Dto
  @PostMapping( value = "/mgmt", params = "Add" )
  public ModelAndView add( @ModelAttribute("dto") Dto dto ) {
    this.dto = dto;                         // Binding List((re) set/change if changed or not)
    dto.add( nextID.getAndDecrement() );    // Add new entry to the list (these IDs will be ignored when creating new set @OneToMany)
    return new ModelAndView( "form", "dto", dto );
  }
}

Any better ideas? I tried to check in keepDto method if user's Dto already exist, but probably I don't understand how that should be achieved properly. Thanks for ideas in advance.

Jan Tibar
  • 46
  • 5
  • Your last sample is dangerous and isn't thread safe. When m multiple users are using this they use each others `Dto`. Also what has security to do with this? Please add your actual controller, that doesn't work (according to you). What you should be using is `@SessionAttributes` to store the dto in the users HTTP session for re-use. – M. Deinum Nov 19 '20 at 06:25
  • I don't see that multiple users are using the same Dto, when I am testing it with two different users from two different web browsers. BTW of course Dto is @SessionScope as RSPEC suggest. – Jan Tibar Nov 19 '20 at 08:00
  • No the DTO isn't session scoped, as you are creating a new instance yourself. If 2 concurrent requests come in, they will override each other. And that will happen sometime leading to issues. So again what you are currently doing is dangerous. And as mentioned you should be using `@SessionAttributes` on your controller to determine what to stick in the session. – M. Deinum Nov 19 '20 at 08:13

0 Answers0