如何从前端向 Spring 发出 HTTP POST 请求?

Jor*_*dan 2 javascript java rest spring http

我正在尝试使用 ReactJS 作为前端和通过 Spring 连接的 Java 后端来设置 web 应用程序,但我是 Spring 的新手。

我现在在 RestController 中设置了两个不同的请求:

@RequestMapping(value = "/index")
public String index() {
        return "index string!";
}

@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestParam("user") User user) {
        System.out.println(user);
}
Run Code Online (Sandbox Code Playgroud)

我可以像这样从前端成功查询/index:

fetch("http://localhost:3002/index").then(function(response) {
    console.log(response.text());
    return response;
});
Run Code Online (Sandbox Code Playgroud)

这将打印一个包含字符串“索引字符串!”的 Promise。(我也不确定如何使用这个字符串,但这不是我的主要问题)

我想使用 POST 请求(应该是 PUT 吗?)发送数据供用户登录。我的计划是从请求中获取用户对象,并在 Java 代码中的其他位置根据我的数据库验证该对象。这是一个用户对象:

public class User {
  private String username;
  private String password;

  public User(String uName, String pass) {
    username = uName;
    password = pass;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是前端的 POST 请求:

fetch('http://localhost:3002/login', {
        method: 'POST',
        body: {
          username: username,
          password: password
        }
    });
Run Code Online (Sandbox Code Playgroud)

其中用户名和密码是从 HTML 解析的字符串。

我的理解是 Spring 应该从请求的主体创建一个用户对象并让我使用它,但是我收到了 400 错误,没有更多细节。

我怎样才能让这个 400 错误消失并成功地将数据从我的前端传递到我的后端?

编辑:这是返回错误的前几行

VM10542:1 POST http://localhost:3002/login 400 ()
(anonymous) @   VM10542:1
func    @   LoginPage.js:26
Run Code Online (Sandbox Code Playgroud)

LoginPage.js:26 是 fetch 调用。

paw*_*rol 6

首先,是的 POST 是此类调用的正确方法。

在您的情况下,您有两种选择:

将数据作为正文发送
,以便端点实现如下所示:

@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestBody User user) { 
    System.out.println(user);
}
Run Code Online (Sandbox Code Playgroud)

然后将其作为 JSON 发送

fetch('http://localhost:3002/login', {
  method: "POST",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    username: "foo",
    password: "bar"
  })
});
Run Code Online (Sandbox Code Playgroud)

或者在 params 中发送,
这样端点的实现就会是这样的:

@RequestMapping(method=RequestMethod.POST, value="/login")
public void login(@RequestParam("username") String username,
                  @RequestParam("password") String password) { 
    System.out.println(username + " " + password);
}
Run Code Online (Sandbox Code Playgroud)

然后在参数中发送它(不是最好的实现):

fetch('http://localhost:3002/login?username=' + username 
                                 + '&password=' + password, {
  method: "POST",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json"
  }
});
Run Code Online (Sandbox Code Playgroud)

当然,您应该记住,简单地发送密码不是一个好主意,但我相信这是出于学习目的。在其他情况下,您可以查看 HTTPS。

您还可以查看其他登录处理技术,例如初学者 JWT,或者您可以介绍 OAUTH。祝你好运!

编辑:

我没有注意到你的模型类是错误的。我相信你需要让它看起来像这样:

class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以 Spring 告诉你构造函数是错误的,因为他找不到usernamepassword字段的正确映射。