如何在Web服务的请求之间保留数据?

时间:2018-07-31 14:17:15

标签: spring rest soap stateless stateful

假设我开发了票单Web服务。有一些订购票证的步骤,并且需要在步骤之间保留一些用户数据。

假设我使用Spring(Boot)技术堆栈和MVC

如何更好地实施它?

  1. 使用无状态REST,并使用cookie一步一步地移动日期?
  2. 将其存储在会话上下文中吗?
  3. 使用有状态的bean(在春季它们是什么样?原型?)
  4. 使用某种有状态协议,例如SOAP(有状态吗?)

1 个答案:

答案 0 :(得分:1)

要视情况而定。

1如果您要使用Web服务的多个实例(用于平衡负载等),则选择无状态REST和基于令牌的身份验证

2如果不需要此功能,则可以将会话信息存储在MVC模型中(无论如何它都会将其放入会话中)

@RestController
@SessionAttributes("armUserSession")
public class SessionController {

    @Autowired
    private LoginService loginService;

    @ModelAttribute("armUserSession")
    public ArmUserSession getArmUserSession() {
        return new ArmUserSession();
    }

    @CrossOrigin
    @RequestMapping({"/login"})
    public ArmUserSession login(@ModelAttribute("armUserSession") ArmUserSession userSession,
                                Model model,
                                @RequestParam(required = false) String login,
                                @RequestParam(required = false) String password) {
        if (!userSession.isLoggedIn()) {
            userSession = loginService.login(login, password);
            model.addAttribute("armUserSession", userSession);
        }

        return userSession;
}

    @CrossOrigin
    @RequestMapping({"/logout"})
    public ArmUserSession logout(SessionStatus status) {
        status.setComplete();
        return new ArmUserSession();
    }


}

3您也可以使用会话范围的Bean,但这要复杂一些。 默认情况下,Spring bean是单例。如果要在单例中使用会话作用域的bean(不是单例),则需要一个代理。

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private ArmUserSessionProxy armUserSessionProxy;

    @Override
    public ArmUserSession login(String login, String password) {
        ArmUserSession armUserSession = armUserSessionProxy.getArmUserSession();

...................................
}

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ArmUserSessionProxy {

    private ArmUserSession armUserSession = new ArmUserSession();

    public ArmUserSession getArmUserSession() {
        return armUserSession;
    }

}