Spring 从用户界面启动 AJAX POST 请求和 knockout.js 调试错误

Spring boot AJAX POST request and knockout.js debug error from user interface

我有两个 java models 作为球员和球队。我有一个控制器 class。当我从用户界面通过 ajax 发送 post 请求时出现错误。我已经解决了像 CORS 这样的错误。但是有一个错误我无法解决; knockout.js 调试错误和 post 请求没有发生。我的数据库没有变化。我分享了模型 classes、控制器 class、html 和 javascript 文件。

我需要更改什么?你能帮忙吗?

球员模型

@Entity
@Table(name = "player")
public class Player{

    @Id
    @GeneratedValue
    @NotNull
    @Column
    private int id;

    @NotNull
    @Column
    private String playerName;

    @NotNull
    @Column
    private String playerSurname;

    @Column
    private int playerAge;



    public String getPlayerName() {
        return playerName;
    }

    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }

    public String getPlayerSurname() {
        return playerSurname;
    }

    public void setPlayerSurname(String playerSurname) {
        this.playerSurname = playerSurname;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getPlayerAge() {
        return playerAge;
    }

    public void setPlayerAge(int playerAge) {
        this.playerAge = playerAge;
    }
}

团队模型

@Entity
@Table(name = "team")
public class Team {

    @Id
    @GeneratedValue
    @NotNull
    @Column
    private int id;

    @NotNull
    @Column
    private String teamName;

    @Column
    private String teamCountry;

    public Team(){
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTeamName() {
        return teamName;
    }

    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }

    public String getTeamCountry() {
        return teamCountry;
    }

    public void setTeamCountry(String teamCountry) {
        this.teamCountry = teamCountry;
    }

    @ManyToOne
    private Player player;

    public Player getPlayer() {
        return player;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }
}

控制器

@CrossOrigin(origins = "http://localhost:8000/")
@RestController
public class TeamController {
    @Autowired
    PlayerRepository playerRepository;
    @Autowired
    TeamRepository teamRepository;

    @RequestMapping("/")
    public void main() {

        //create players by manual
        Player messi = new Player();
        Player ronaldo = new Player();
        Player ozil = new Player();

        messi.setPlayerName("Lionel");
        messi.setPlayerSurname("Messi");
        messi.setPlayerAge(31);

        ronaldo.setPlayerName("Cristiano");
        ronaldo.setPlayerSurname("Ronaldo");
        ronaldo.setPlayerAge(32);

        ozil.setPlayerName("Mesut");
        ozil.setPlayerSurname("Ozil");
        ozil.setPlayerAge(29);

        this.playerRepository.save(messi);
        this.playerRepository.save(ronaldo);
        this.playerRepository.save(ozil);

        //create teams by manual    
        Team barcelona = new Team();
        Team juventus = new Team();
        Team arsenal = new Team();

        barcelona.setTeamName("Barcelona");
        barcelona.setTeamCountry("Spain");
        barcelona.setPlayer(messi);

        juventus.setTeamName("Juventus");
        juventus.setTeamCountry("Italy");
        juventus.setPlayer(ronaldo);

        arsenal.setTeamName("Arsenal");
        arsenal.setTeamCountry("England");
        arsenal.setPlayer(ozil);

        this.teamRepository.save(barcelona);
        this.teamRepository.save(juventus);
        this.teamRepository.save(arsenal);

    }   

    //**PLAYER**
    @GetMapping(value="/getAllPLayers")
    public List<Player> getAllPlayers(){
        return playerRepository.findAll();
    }

    @PostMapping(value="getPlayerByName")
    public List<Player> getPlayerByName(@RequestParam("playerName") String playerName){
        return playerRepository.findByPlayerName(playerName);
    }

    @PostMapping(value="getPlayerBySurname")
    public List<Player> getPlayerBySurname(@RequestParam("playerSurname") String playerSurname){
        return playerRepository.findByPlayerSurname(playerSurname);
    }   

    @PostMapping(value="getPlayerByAge")
    public List<Player> getPlayerByAge(@RequestParam("playerAge") int playerAge){
        return playerRepository.findByPlayerAge(playerAge);
    }

    @PostMapping(value="createNewPlayer")
    public Player createNewPlayer(@Valid @RequestBody Player player) {
        return playerRepository.save(player);
    }


    //**TEAM**
    @GetMapping(value="/getAllTeams")
    public List<Team> getAllTeams(){
        return teamRepository.findAll();
    }

    @PostMapping(value = "/getTeamsByName")
    public List<Team> getTeamByName(@RequestParam("teamName") String teamName){
        return teamRepository.findByTeamName(teamName);
    }

    @PostMapping(value = "/getTeamsByCountry")
    public List<Team> getTeamByCountry(@RequestParam("teamCountry") String teamCountry){
        return teamRepository.findByTeamCountry(teamCountry);
    }

@PostMapping(value="/createNewTeam")
public Team createNewTeam(@Valid @RequestBody Player player,@RequestBody Team team) {
    playerRepository.save(player);
    team.setPlayer(player);
    return teamRepository.save(team);
}

}

配置

@Configuration
@EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {


    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
      HttpServletResponse response = (HttpServletResponse) res;
      HttpServletRequest request = (HttpServletRequest) req;
      System.out.println("WebConfig; "+request.getRequestURI());
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
      response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
      response.setHeader("Access-Control-Max-Age", "3600");
      response.setHeader("Access-Control-Allow-Credentials", "true");
      response.setHeader("Access-Control-Expose-Headers", "Authorization");
      response.addHeader("Access-Control-Expose-Headers", "USERID");
      response.addHeader("Access-Control-Expose-Headers", "ROLE");
      response.addHeader("Access-Control-Expose-Headers", "responseType");
      response.addHeader("Access-Control-Expose-Headers", "observe");
      System.out.println("Request Method: "+request.getMethod());
      if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
          try {
              chain.doFilter(req, res);
          } catch(Exception e) {
              e.printStackTrace();
          }
      } else {
          System.out.println("Pre-flight");
          response.setHeader("Access-Control-Allow-Origin", "*");
          response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
          response.setHeader("Access-Control-Max-Age", "3600");
          response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
          "USERID"+"ROLE"+
                  "access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
          response.setStatus(HttpServletResponse.SC_OK);
      }
    }
}

玩家回购

public interface PlayerRepository extends JpaRepository<Player, Integer>{
    List<Player> findByPlayerName(String playerName);
    List<Player> findByPlayerSurname(String playerSurname);
    List<Player> findByPlayerAge(int playerAge);
}

团队回购

public interface TeamRepository extends JpaRepository<Team, Integer>{
    List<Team> findByTeamName(String teamName);
    List<Team> findByTeamCountry(String teamCountry);

}

POST HTML 页数

<!DOCTYPE HTML>
<html>
<head>
      <title>Team Management</title>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" />
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
            <script src="js/restGetPlayer.js"></script>
            <script src="js/restGetTeam.js"></script>
            <script src="js/postTeam.js"></script>
</head>
<body>

<div class="container">
    <h3 style="color: darkolivegreen" align="center">Create a new team</h3>

    <div class"main-block>
        <form id="teamForm" class="form-inline" style="margin:20px 20px 20px 20px">
        <div class="form-group">
                <label for="playerName" style="margin-left:20px; margin-right:5px">Player Name:</label>
                <input type="text" class="form-control" id="playerName" placeholder="Enter player name"/>
        </div>  
        <br>
        <div class="form-group">
                <label for="playerSurname" style="margin-left:20px; margin-right:5px">Player Surname:</label>
                <input type="text" class="form-control" id="playerSurname" placeholder="Enter player surname"/>
        </div> 
        <div class="form-group">
                <label for="playerAge" style="margin-left:20px; margin-right:5px">Player Age:</label>
                <input type="text" class="form-control" id="playerAge" placeholder="Enter player age"/>
        </div>       
        <br style="clear: both;">
            <div class="form-group">
                <label for="teamName" style="margin-right:5px">Team Name:</label>
                <input type="text" class="form-control" id="teamName" placeholder="Enter team name"/>
            </div>
            <br>
            <div class="form-group">
                <label for="teamCountry" style="margin-left:20px; margin-right:5px">Team Country:</label>
                <input type="text" class="form-control" id="teamCountry" placeholder="Enter team country"/>
            </div>          
            <br>
            <hr>
            <button type="submit" class="btn btn-default" style="margin-left:20px; margin-right:5px" >Submit Team</button>
        </form>
    </div>

    <div class="col-sm-7" style="margin:20px 0px 20px 0px">
        <button id="getAllTeams" class="btn btn-primary">Get Team Information</button>
        <div id="getResultDiv3" style="padding:20px 10px 20px 50px">
          <ul class="list-group">
        </ul>
      </div>
    </div>
</div>
<style>
.container {
  max-width: 400px;
  width: 100%;
  margin: 0 auto;
  position: relative;
}
#contact {
  background: #F9F9F9;
  padding: 25px;
  margin: 150px 0;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
</style>
<script type="text/javascript" src="js/libs/require/require.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>

AJAX POST

$( document ).ready(function() {

    $("#teamForm").submit(function(event) {
        event.preventDefault();
        ajaxPost();
    });

    function ajaxPost(){

        var formData = {
            playerName :  $("#playerName").val(),
            playerSurname :  $("#playerSurname").val(),
            playerAge :  $("#playerAge").val(),
            teamName : $("#teamName").val(),
            teamCountry :  $("#teamCountry").val()
        }

        $.ajax({
            type : "POST",
            contentType : "application/json",
            url : "http://localhost:8080" + "/createNewTeam",
            data : JSON.stringify(formData),
            dataType : 'json',

            success: function(result){
                alert("Teams loaded!");
                console.log(result);
                $('#getResultDiv3 ul').empty();
                var tableTitle = "<h2><strong>Team List</strong></h2>";
                var teamList = "<table border='1'>";
                teamList += "<tr><td><strong>Team Name</strong></td><td><strong>Team Country</strong></td><td><strong>Player Name</strong></td><td><strong>Player Surname</strong></td><td><strong>Player Age</strong></td></tr>";

                $.each(result, function(i, teams){
                    teamList +="<tr>";
                    teamList +="<td>"+teams.teamName +"</td>";
                    teamList +="<td>"+teams.teamCountry+"</td>";
                    teamList +="<td>"+teams.player.playerName+"</td>";
                    teamList +="<td>"+teams.player.playerSurname+"</td>";
                    teamList +="<td>"+teams.player.playerAge+"</td>";
                    teamList +="</tr>";
                });
                teamList +="</table>";
                $('#getResultDiv3').append(tableTitle, teamList)
                console.log("Success: ", result);
        },
            error : function(e) {
                $("#getResultDiv3").html("<strong>Error</strong>");
                console.log("ERROR: ", e);
            }
        });

        resetData();
    }

    function resetData(){
        $("#playerName").val("");
        $("#playerSurname").val("");
        $("#playerAge").val("");
        $("#teamName").val("");
        $("#teamCountry").val("");

    }
})

MainController.js

/**
 * @license
 * Copyright (c) 2014, 2019, Oracle and/or its affiliates.
 * The Universal Permissive License (UPL), Version 1.0
 */
/*
 * Your application specific code will go here
 */
define(['ojs/ojresponsiveutils', 'ojs/ojresponsiveknockoututils', 'knockout', 'ojs/ojknockout'],
  function(ResponsiveUtils, ResponsiveKnockoutUtils, ko) {
     function ControllerViewModel() {
       var self = this;

      // Media queries for repsonsive layouts
      var smQuery = ResponsiveUtils.getFrameworkQuery(ResponsiveUtils.FRAMEWORK_QUERY_KEY.SM_ONLY);
      self.smScreen = ResponsiveKnockoutUtils.createMediaQueryObservable(smQuery);

      // Header
      // Application Name used in Branding Area
      self.appName = ko.observable("Oracle JET + REST API");
      // User Info used in Global Navigation area
      self.userLogin = ko.observable("admin@oracle.com");

      // Footer
      function footerLink(name, id, linkTarget) {
        this.name = name;
        this.linkId = id;
        this.linkTarget = linkTarget;
      }
      self.footerLinks = ko.observableArray([
        new footerLink('About Oracle', 'aboutOracle', 'http://www.oracle.com/us/corporate/index.html#menu-about'),
        new footerLink('Contact Us', 'contactUs', 'http://www.oracle.com/us/corporate/contact/index.html'),
        new footerLink('Legal Notices', 'legalNotices', 'http://www.oracle.com/us/legal/index.html'),
        new footerLink('Terms Of Use', 'termsOfUse', 'http://www.oracle.com/us/legal/terms/index.html'),
        new footerLink('Your Privacy Rights', 'yourPrivacyRights', 'http://www.oracle.com/us/legal/privacy/index.html')
      ]);
     }

     return new ControllerViewModel();
  }
);

图片1: Adding Player

图二: ERROR log After add player

图3: MySQL player table did not any change

回答你的问题,它没有做任何事情,因为你没有发送参数播放器(必须有效),因为你使用的是表单,这不是你应该做的方式。 (请求参数通过 url 发送,您的表单应通过 @RequestBody 发送)

检查此 post 以获取信息。

我会这样做:

在我的控制器上,由于我只能有一个@RequestBody,但是我的表单发送了一个包含多种类型对象数据的对象,我会做一个 Dto

像这样:

@PostMapping(value="/createNewTeam")
    public Team createNewTeam(@Valid @RequestBody PayloadDto payloadDto) {
        final Player player = new Player();
        player.setPlayerName(payloadDto.playerName);
        // fill player information
        final Team team = new Team();
        // fill team information... 
        playerRepository.save(player);
        return teamRepository.save(team);
    }

您的 PayloadDto 对象必须包含您发送的所有属性..

public class PayloadDto{

  @JsonProperty("playerName")
  public String playerName;
  @JsonProperty("playerSurname")
  public String playerSurname;
  // .. more player and team properties 
}

确保 jsonProperty("propertyName) 与您在发送信息时使用的名称相同