如何在 Web 服务请求之间保留数据?
How to keep a data between requests at web service?
假设我开发了一个订票网络服务。订票有一些步骤,需要在步骤之间保留一些用户数据。
假设我使用Spring(Boot)技术栈和MVC
怎样实施比较好?
- 使用无状态 REST 并使用 cookie 来回移动日期?
- 将其存储在会话上下文中?
- 使用有状态 bean(它们在 Spring 中是什么样子?原型?)
- 使用一些有状态的协议,比如 SOAP(它是有状态的吗?)
视情况而定。
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;
}
}
假设我开发了一个订票网络服务。订票有一些步骤,需要在步骤之间保留一些用户数据。
假设我使用Spring(Boot)技术栈和MVC
怎样实施比较好?
- 使用无状态 REST 并使用 cookie 来回移动日期?
- 将其存储在会话上下文中?
- 使用有状态 bean(它们在 Spring 中是什么样子?原型?)
- 使用一些有状态的协议,比如 SOAP(它是有状态的吗?)
视情况而定。
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;
}
}