英文:
Spring Boot returning error Content type 'text/plain;charset=UTF-8' not supported
问题
我尝试从我的JavaScript文件向本地主机的服务器发送POST请求,以验证登录。
这是我的前端代码:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WorkSoftManager - 登录</title>
<link rel="stylesheet" type="text/css" href="styleLogin.css">
</head>
<body>
<div class="container">
<h1>WorkSoftManager</h1>
<h2>登录</h2>
<form id="login-form">
<input type="email" id="username" placeholder="电子邮件" required>
<input type="password" id="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
<p>没有账户?<a href="signUp.html">注册</a></p>
</div>
<script src="script.js"></script>
</body>
</html>
JavaScript
// 创建处理登录过程的函数
async function login(username, password) {
try {
const response = await fetch('http://localhost:8080/api/login/', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
'username': username,
'password': password
})
});
// 检查响应是否成功
if (!response.ok) {
throw new Error('登录失败。请重试。');
}
// 解析响应的JSON数据
const data = await response.json();
// 检查身份验证是否成功
if (!data.authenticated) {
throw an Error('无效的用户名或密码。');
}
// 将身份验证令牌存储在本地存储中
localStorage.setItem('token', data.token);
// 重定向用户到loginPage.html页面
window.location.href = '/loginPage.html';
} catch (error) {
// 显示错误消息
alert(error.message);
}
}
// 附加事件侦听器到登录表单的提交按钮
document.getElementById('login-form').addEventListener('submit', (event) => {
event.preventDefault();
// 获取用户名和密码输入的值
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
// 使用用户名和密码调用登录函数
login(username, password);
});
// 创建处理注销过程的函数
function logOff() {
// 从本地存储中移除身份验证令牌
localStorage.removeItem('token');
// 重定向用户到登录页面
window.location.href = '/loginPage.html';
}
// 附加事件侦听器到注销链接
//document.getElementById('log-off-link').addEventListener('click', logOff);
Spring REST Controller
@RestController
@RequestMapping("/api")
public class WSMController {
private Map<String, UserSession> sessions = new HashMap<>();
@Autowired
private WSMService service;
@PostMapping(value = "/login")
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
User user = authenticate(request);
if (user == null) {
return ResponseEntity.badRequest().body("无效的用户名或密码");
}
String token = UUID.randomUUID().toString();
UserSession session = new UserSession(user, token);
sessions.put(token, session);
return ResponseEntity.ok(token);
}
@PostMapping("/logoff")
public ResponseEntity<String> logoff(@RequestHeader("Authorization") String token) {
sessions.remove(token.substring(7));
return ResponseEntity.ok("用户成功注销");
}
@GetMapping("/user")
public User getUser(@RequestHeader("Authorization") String token) {
UserSession session = sessions.get(token.substring(7));
if (session == null) {
return null;
}
return session.getUser();
}
private User authenticate(LoginRequest request) {
if(!service.getCredentials(request)) {
return null;
}
return new User(request.getUsername(),request.getPassword());
}
}
LoginRequest DTO
package com.worksoftmanager.WorkSoftManagerAuthenticator.model;
public class LoginRequest {
private String username;
private password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
这是服务器端的错误消息:
2023-02-06 10:43:10.674 WARN 20380 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain;charset=UTF-8' not supported]
我已尝试设置头部以发送"application/json"内容并更改RequestMapping以消耗"Application_JSON_Value",但都没有成功。
英文:
I'm trying to send a POST from my javascript file to a server local host which will validate the login.
Here is my front end code:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WorkSoftManager - Login</title>
<link rel="stylesheet" type="text/css" href="styleLogin.css">
</head>
<body>
<div class="container">
<h1>WorkSoftManager</h1>
<h2>Login</h2>
<form id="login-form">
<input type="email" id="username" placeholder="Email" required>
<input type="password" id="password" placeholder="Password" required>
<button type="submit">Login</button>
</form>
<p>Don't have an account? <a href="signUp.html">Sign Up</a></p>
</div>
<script src="script.js"></script>
</body>
</html>
JavaScript
// Create a function to handle the login process
async function login(username, password) {
try {
const response = await fetch('http://localhost:8080/api/login/', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
'username' : username,
'password': password
})
});
// Check if the response was successful
if (!response.ok) {
throw new Error('Login failed. Please try again.');
}
// Parse the response JSON data
const data = await response.json();
// Check if the authentication was successful
if (!data.authenticated) {
throw new Error('Invalid username or password.');
}
// Store the authentication token in local storage
localStorage.setItem('token', data.token);
// Redirect the user to the loginPage.html page
window.location.href = '/loginPage.html';
} catch (error) {
// Show an error message
alert(error.message);
}
}
// Attach an event listener to the login form submit button
document.getElementById('login-form').addEventListener('submit', (event) => {
event.preventDefault();
// Get the values of the username and password inputs
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
// Call the login function with the username and password
login(username, password);
});
// Create a function to handle the log off process
function logOff() {
// Remove the authentication token from local storage
localStorage.removeItem('token');
// Redirect the user to the login page
window.location.href = '/loginPage.html';
}
// Attach an event listener to the log off link
//document.getElementById('log-off-link').addEventListener('click', logOff);
Spring REST Controller
@RestController
@RequestMapping("/api")
public class WSMController {
private Map<String, UserSession> sessions = new HashMap<>();
@Autowired
private WSMService service;
@PostMapping(value = "/login")
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
User user = authenticate(request);
if (user == null) {
return ResponseEntity.badRequest().body("Invalid username or password");
}
String token = UUID.randomUUID().toString();
UserSession session = new UserSession(user, token);
sessions.put(token, session);
return ResponseEntity.ok(token);
}
@PostMapping("/logoff")
public ResponseEntity<String> logoff(@RequestHeader("Authorization") String token) {
sessions.remove(token.substring(7));
return ResponseEntity.ok("User logged off successfully");
}
@GetMapping("/user")
public User getUser(@RequestHeader("Authorization") String token) {
UserSession session = sessions.get(token.substring(7));
if (session == null) {
return null;
}
return session.getUser();
}
private User authenticate(LoginRequest request) {
if(!service.getCredentials(request)) {
return null;
}
return new User(request.getUsername(),request.getPassword());
}
LoginRequest DTO
package com.worksoftmanager.WorkSoftManagerAuthenticator.model;
public class LoginRequest {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Here is the error message from server side:
2023-02-06 10:43:10.674 WARN 20380 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain;charset=UTF-8' not supported]
I've tried set the headers to send an application/json
content and change the RequestMapping
to consume Application_JSON_Value
, but none of it worked.
---------Testing response-----------:
----John's response:
After I make the request, I got this message on console:
Error using await response.json()
----David's response:
Headers:
Body:
答案1
得分: 0
我认为这个 JSON 不好。尝试:
body: JSON.stringify({
'username': username,
'password': password
})
另外,mode: 'no-cors'
会强制 content-type 为文本。要么将其移除,要么设置为 mode: 'cors'
- 参见 no-cors breaks content-type header。
英文:
I think that the JSON isn't good. Try
body: JSON.stringify({
'username' : username,
'password': password
})
Also the mode: 'no-cors'
will force the content-type to text. Either take it out or set mode: 'cors'
- see no-cors breaks content-type header
答案2
得分: 0
@PostMapping
或其他映射可以设置特定的输入/输出 ContentTypes
@PostMapping(path = "/login", consumes = "application/json", produces = "application/json")
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
...
return ResponseEntity;
}
其他了解 Spring @PostMapping
的参考:
(Baeldung) @RequestMapping Consumes and Produces
(Stackoverflow) What is produce and consume in @Request Mapping
对于 JavaScript 部分,问题出在 mode: 'no-cors'
解决方法之一是更改 Java 代码:
JSON to Java Object
@PostMapping(path = "/login", consumes = "text/plain", produces = "application/json")
public ResponseEntity<String> login(@RequestBody String request) {
ObjectMapper objectMapper = new ObjectMapper();
LoginRequest loginRequest = objectMapper.readValue(json, LoginRequest.class);
...
return ResponseEntity;
}
英文:
@PostMapping
or other mappings can be set to specific input/output ContentTypes
@PostMapping(path = "/login", consumes = "application/json", produces = "application/json")
public ResponseEntity<String> login(@RequestBody LoginRequest request) {
...
return ResponseEntity;
}
Other references to understand Spring @PostMapping:
(Baeldung) @RequestMapping Consumes and Produces
(Stackoverflow) What is produce and consume in @Request Mapping
For the JavaScript part.
The problem is with mode: 'no-cors'
A way to get arround with that is changing the java:
JSON to Java Object
@PostMapping(path = "/login", consumes = "text/plain", produces = "application/json")
public ResponseEntity<String> login(@RequestBody String request) {
ObjectMapper objectMapper = new ObjectMapper();
LoginRequest loginRequest = objectMapper.readValue(json, LoginRequest.class);
...
return ResponseEntity;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论