Java 如何使spring boot rest api成为有状态的

Java 如何使spring boot rest api成为有状态的,java,rest,spring-boot,javabeans,stateful,Java,Rest,Spring Boot,Javabeans,Stateful,我想用REST和spring boot制作web应用程序。RESTWeb服务是无状态的。我想使它有状态,以便在第一个请求之后发送给客户机的信息服务器应该在下一个请求中使用。或者,将进一步使用在第一个或第二个请求中完成的执行。 我们是否可以为该会话生成一些会话id,并且该会话id客户端可以在后续请求中发送给服务器?如果是,那么 如果某些对象/bean的状态正在更改(由于某些操作而修改了值)。那么我们如何以对象/bean的顺序保存状态以使其有状态,这些bean的作用域是什么(其值将被修改)当多个客户

我想用REST和spring boot制作web应用程序。RESTWeb服务是无状态的。我想使它有状态,以便在第一个请求之后发送给客户机的信息服务器应该在下一个请求中使用。或者,将进一步使用在第一个或第二个请求中完成的执行。 我们是否可以为该会话生成一些会话id,并且该会话id客户端可以在后续请求中发送给服务器?如果是,那么
如果某些对象/bean的状态正在更改(由于某些操作而修改了值)。那么我们如何以对象/bean的顺序保存状态以使其有状态,这些bean的作用域是什么(其值将被修改)当多个客户端或用户将使用此web应用程序时,将调用这些bean的类/bean?

会话通常是一种优化,用于在运行多个服务器时提高性能。它们通过确保客户端请求始终被发送到缓存客户端数据的同一服务器来提高性能

如果您只想运行一台服务器,就不必担心会话。有两种常见的方法来解决这个问题

1.内存状态 如果您想要维护的状态足够小,可以放入内存,并且您不介意在服务器崩溃或重新启动时丢失它,那么您可以将其保存在内存中。您可以创建一个包含数据结构的spring服务。然后,您可以将该服务注入控制器并更改http处理程序中的状态

默认情况下,服务是单例的。因此,所有控制器、组件和用户请求都可以访问存储在服务中的状态。下面是一个小的伪示例

服务等级 注意:如果您在负载平衡器后面运行多台服务器,这种方法将不起作用,除非您使用更复杂的解决方案,如分布式缓存。在这种情况下,会话可用于优化性能

2.数据库 另一种选择是只使用数据库来存储您的状态。这样,在崩溃或重新启动时不会丢失数据。Spring支持hibernate持久性框架,您可以运行类似Postgres的数据库

注意:如果要运行多台服务器,则需要更复杂的解决方案,因为hibernate将数据缓存在内存中。您必须将hibernate插入分布式缓存,以便跨多个服务器同步内存中的状态。在这里,会话可以用作性能优化

重要的
无论何时修改状态,您都需要确保以线程安全的方式执行,否则您的状态可能不正确。

会话通常是一种优化,可在运行多台服务器时提高性能。它们通过确保客户端请求始终被发送到缓存客户端数据的同一服务器来提高性能

如果您只想运行一台服务器,就不必担心会话。有两种常见的方法来解决这个问题

1.内存状态 如果您想要维护的状态足够小,可以放入内存,并且您不介意在服务器崩溃或重新启动时丢失它,那么您可以将其保存在内存中。您可以创建一个包含数据结构的spring服务。然后,您可以将该服务注入控制器并更改http处理程序中的状态

默认情况下,服务是单例的。因此,所有控制器、组件和用户请求都可以访问存储在服务中的状态。下面是一个小的伪示例

服务等级 注意:如果您在负载平衡器后面运行多台服务器,这种方法将不起作用,除非您使用更复杂的解决方案,如分布式缓存。在这种情况下,会话可用于优化性能

2.数据库 另一种选择是只使用数据库来存储您的状态。这样,在崩溃或重新启动时不会丢失数据。Spring支持hibernate持久性框架,您可以运行类似Postgres的数据库

注意:如果要运行多台服务器,则需要更复杂的解决方案,因为hibernate将数据缓存在内存中。您必须将hibernate插入分布式缓存,以便跨多个服务器同步内存中的状态。在这里,会话可以用作性能优化

重要的
无论何时修改状态,您都需要确保以线程安全的方式进行,否则您的状态可能不正确。

Restful API在设计上不是有状态的,如果您使用服务器端使它们有状态,那么它就不是REST


您需要的是一个相关Id,它是分布式系统设计中公认的模式。关联Id将允许您将请求绑定在一起。

Restful API的设计不是有状态的,如果您使用服务器端使它们有状态,那么它就不是REST


您需要的是一个相关Id,它是分布式系统设计中公认的模式。关联Id将允许您将请求联系在一起。

您可以更明确地回答您的问题吗?并提供一些您已经采用的示例。妮特:如果它是有状态的,那么根据定义它不是REST。@JonathanJohx-我没有编写任何代码,我仍在进行设计。我的问题的第一部分是,我们可以使用SpringBoot作为有状态的RESTAPI吗?可能是通过创建一些会话id或令牌,客户端可以在对我的web api的不同/进一步调用中使用这些id或令牌?没关系,谢谢。所以我同意@Krease。你能更明确地回答你的问题吗?并提供一些您已经采用的示例。妮特:如果它是有状态的,那么根据定义它不是REST。@JonathanJohx-我没有编写任何代码,我仍在进行设计。我的问题的第一部分是,我们可以使用SpringBoot作为有状态的RESTAPI吗?可能是通过创建一些会话id或令牌,客户端可以在对我的web api的不同/进一步调用中使用这些id或令牌?没关系,谢谢。所以我同意@Krease。
@Service
public class MyState
{
  private Map<String, Integer> sums = new HashMap<>();

  public synchronized int get(String key) {
    return sums.get(key);
  }

  public synchronized void add(String key, int val) {
    int sum = 0;

    if (sums.contains(key)) {
      sum = sum.get(key);
    }

    sum += val;

    sums.put(key, (Integer)sum);
  }
}
@RestController
@RequestMapping("/sum")
public class FactoryController
{
  @Autowired
  private MyState myState;

  @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
  @ResponseStatus(HttpStatus.OK)
  @ResponseBody
  public SuccessResponse saveFactory(@RequestBody KeyVal keyVal)
  {
    myState.add(keyVal.getKey(), keyVal.getValue());
  }
}