在Spring中将状态存储在控制器中

时间:2018-08-30 20:50:22

标签: java spring forms model-view-controller javabeans

寻找一些建议,尝试制作纸牌游戏。我是Spring MVC的完整入门者(如果以下问题尚未解决)。

使用范围为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);
  }
}

控制器

@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();
  }

发出请求的反应组件

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中提出这些请求时,一切都很好。它可以正常工作-触发后路由并添加了一个新玩家,当我触发“获取”路由时,它将返回所有添加了新玩家的玩家。

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

我的猜测是,这个可能可能归因于对该Bean的工作原理的基本误解。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

行,

这里有些不对劲。首先让我们从Game类开始。用@Component注释。这意味着Spring的自动类路径扫描可以自动进行配置。话虽如此,您随时都可以使用它进行注射。同时,这意味着您在ApplicationConfig类中执行的手动声明是不必要的。在这里,您手动实例化Game并尝试使用@Bean批注将其引入Spring上下文。这是错误的,并可能导致意外结果。要么保留@Component类,要么保留另一个。

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

最后将所有这些都放置到位,只需将Game类注入到PlayerController中(也请确保使用首选的基于构造函数的DI方法进行此操作),您应该会做得很好。 / p>

最后,我建议您在进行此操作之前先了解一下Spring和一般的DI的工作原理,否则会遇到问题。

编辑:同样如上述答案所述,客户端也应进行更改。

答案 1 :(得分:0)

将@RequestParam更改为@RequestBody 并尝试使用类似的东西

id<MTLTexture>