java - 在 Spring 的 Controller 中存储状态

标签 java spring forms model-view-controller javabeans

寻求一些建议,尝试制作一款纸牌游戏。我是 Spring MVC 的完全初学者(如果以下问题还没有透露这一点..)

使用代理 session 范围 Bean 来管理游戏状态,我的路线似乎可以使用 Postman 正常工作,并且能够创建新玩家。

游戏类

@Component
public class Game {
private Deck deck;
private ArrayList<Player> players;
private HashMap<Player, Integer> wins;

@Autowired
public Game(Deck deck){
    this.deck = deck;
    this.players = new ArrayList<>();
    this.wins = new HashMap<>();
}

public ArrayList<Player> getPlayers() {
    return players;
}

public void addPlayer(String name){
    this.players.add(new Player(name));
<小时/>

ApplicationConfig 类

@EnableWebMvc
@Configuration
@ComponentScan("com.kane.cardgame")
public class ApplicationConfig {
  private Deck deck = new Deck();

  @Bean
  @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = 
  ScopedProxyMode.TARGET_CLASS)
  public Game game(){
    return new Game(deck);
  }
}
<小时/>

Controller

@CrossOrigin
@RestController(value="PlayerController")
@RequestMapping("/game/players")
public class PlayerController {
  @Autowired
  private Game game;

  @RequestMapping(method=RequestMethod.GET, value="/")
  public ArrayList<Player> allPlayers(){
    return game.getPlayers();
  }

  @RequestMapping(method= RequestMethod.POST, value="/")
  public ArrayList<Player> addPlayer(@RequestParam(value="name") String 
  name){
    game.addPlayer(name);
    return game.getPlayers();
  }
<小时/>

发出请求的 React 组件

const handleLinkClick = e => {
const url = `http://localhost:8080/game/players/? 
name=${this.state.name}`
  fetch(url, {
    method: 'POST',
    mode: 'cors'
  })
  .then(res => res.json())
  .then(res => {
    const newState = this.state.newPlayers;
    newState.push(res);
    this.setState({newPlayers: newState})
  })
 }

 return(
 <div>
   <h1>Enter your name</h1>
   <input id="name-input" type="text" name="name" onChange= . 
   {handleNameChange}/>
   <Link to="/newPlayer" onClick={handleLinkClick}>Start Game</Link>
  </div>
  )
<小时/>

当我在 Postman 中提出这些请求时,一切都很好。它按其应有的方式工作 - 触发后路由并添加一名新玩家,当我触发 Get 路由时,它会返回所有添加了新玩家的玩家。

当我使用 React 发出此请求时,它似乎创建了我的 Player 类的实例(因为 id 递增),但它似乎没有将玩家添加到 Game 中包含的 ArrayList 中。我可以让它以 JSON 形式返回刚刚创建的 Player 并将其存储在状态中。但是,当我获取与 Get 路由关联的 URL 以返回游戏玩家时,没有存储任何内容。我的预感是我没有正确存储此游戏状态。

我的猜测是,这可能可以归结为对这个 Bean 工作原理的根本误解。任何建议将不胜感激。

最佳答案

好的,就到这里,

这里有几处不对劲的地方。首先让我们从 Game 开始类(class)。其注释为 @Component 。这意味着 Spring 的自动类路径扫描会自动选择并配置。话虽如此,您可以在需要时随时进行注入(inject)。同时,这意味着您在 ApplicationConfig 中执行的手动安装类是不必要的。在那里您手动实例化 Game并尝试使用@Bean将其带入Spring上下文中注解。这是错误的,可能会导致意想不到的结果。要么保留 @Component类或其他。

其次,Game实际上是一个管理整个游戏的服务组件。考虑到这一点,我建议删除 @Component并添加 @Service注释以更好地表示它的实际用法(毕竟它是一项服务)。 @Autowired它的构造函数上的注释也是不需要的,因为您没有在其中有效地注入(inject)任何 Spring 托管 bean。相反,如果您想执行 post bean 创建操作(即初始化 Deck 对象以及各种列表和映射),只需创建一个新的 void 方法并用 @PostConstruct 对其进行注释。 。同时,请确保将这些声明更改为 private ArrayList<Player> players;private List<Player> players;因为对接口(interface)进行编码总是比实际实现更好。 getPlayers 的返回参数也是如此。 .

最后,所有这些都就位后,只需注入(inject) Game类进入你的PlayerController (还要确保使用基于首选构造函数的 DI 方法来执行此操作),您应该可以开始了。

最后,我建议您在继续之前仔细阅读 Spring 和一般 DI 的工作原理,否则您将不断遇到问题。

编辑:正如上面的答案中提到的,客户端也应该进行更改。

关于java - 在 Spring 的 Controller 中存储状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52105168/

相关文章:

java - 在 spring 应用程序中防止来自 curl/http post 的登录攻击

javascript - 关于将动态数据输入到 html 页面的表单的建议

javascript - 使用javascript在rails 3中提交远程form_tag,但以html形式提交

java - 从 ResultSet 中的资源获取 URI

java - 使用 e(fx)clipse 部署包 - Macos 图标问题

java - ConditionalOnMissingBean 按名称

java - 如何使用 xml 在 spring security 中禁用注销确认?

php - 机器人提交表单的方式与使用浏览器的方式不同吗?

Java 8 ClassFormatException 用于与静态方法的接口(interface),但仅在使用断言时

java - 如何使用Java 8的默认方法在接口(interface)中使用EntityManager实例?