#java #rest #api #angular7
#java #rest #API #angular7
Вопрос:
Это первый раз, когда я разработал Java Rest API. Я пытаюсь интегрировать REST API в Angular 7, но получаю сообщение об ошибке.
415 неподдерживаемых типов носителей
package org.jasyatra.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.jasyatra.model.AdminLogin;
import org.jasyatra.model.LoginAuthToken;
import org.jasyatra.service.AdminLoginService;
import org.jasyatra.service.LoginAuthTokenService;
@RestController
public class AdminLoginController {
@Autowired
AdminLoginService adminLoginService;
@Autowired
LoginAuthTokenService loginAuthTokenService;
@RequestMapping(value = "/admin/login", method = RequestMethod.POST, headers = "Accept=application/json")
public Map login(@RequestBody AdminLogin parameters) {
List<AdminLogin> loginResponse = adminLoginService.login(parameters);
Map<String, String> response = new HashMap<>();
if (loginResponse.size() > 0) {
response.put("result", "true");
response.put("id", Integer.toString(loginResponse.get(0).getId()));
response.put("username", loginResponse.get(0).getUsername());
response.put("role", loginResponse.get(0).getUserRole());
List<LoginAuthToken> responseToken = loginAuthTokenService.getLatestToken(loginResponse.get(0).getId(), loginResponse.get(0).getUserRole());
response.put("token", responseToken.get(0).getToken());
} else {
response.put("result", "false");
response.put("message", "Invalid username or password!");
}
return response;
}
}
adminLogin(params) {
let headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
return this.http.post(this.api_url '/admin/login', params, options).pipe(map((response: any) => response.json()));
}
Если я не отправляю тип содержимого в заголовках, я получаю эту ошибку:
Request Method: OPTIONS
Status Code: 403 Forbidden
Если я отправляю тип содержимого в заголовках, я получаю эту ошибку:
415 Unsupported Media Type
Я пробовал подобные комбинации, но, похоже, ни одна из них не работает для меня.
Не могли бы вы направить меня в правильном направлении.
Спасибо
Комментарии:
1. Ваш метод принимает,
application/json
но вы отправляетеapplication/x-www-form-urlencoded
.2. @Обратная косая черта я отправляю accept: application / json также, как вы можете видеть в коде, и я также упомянул, что если я не отправляю content-type, я получаю Метод запроса: ПАРАМЕТРЫ Код статуса: 403 Запрещенная ошибка
3. Отправка
accept
заголовка от клиента просто сообщает серверу, что ваш клиент способен понятьapplication/json
.Content-Type
сообщает серверу, какие данные вы отправляете,Accept
на стороне сервера означает, что сервер может понимать этот язык. Итак, еслиAccept
с сервера иContent-Type
с клиента не совпадают, вы получите 415. Также может случиться так, что вы получите 415 из-за ошибки десериализации (т. Е. Тело не может быть проанализировано наAdminLogin
), но обычно вместо этого должно срабатывать значение 400.4. @Обратная косая черта, я пробовал это также headers.append(‘Accept’, ‘application / json’); headers.append(‘Content-Type’, ‘application / json’); в этом случае я получаю 403 запрещенную ошибку, а заголовок запросов выглядит следующим образом Заголовки запросов на управление доступом: content-type Access-Control-Request-Method: POST Origin: localhost: 4200 Refererer: localhost: 4200/ страницы/авторизация/вход и я получаю ответ, подобный этому Недействительному запросу CORS
5. Затем вам следует выяснить на стороне сервера, почему это происходит, вероятно, у вас где-то есть журналы.
Ответ №1:
Вы отправляете 'application/x-www-form-urlencoded'
как content-type
. Вам нужно будет указать это в REST API. Вы должны включить consumes
параметр в свой @RequestMapping
. Что-то вроде этого
@RequestMapping(value = "/admin/login", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, headers = "Accept=application/json")
Вам также нужно будет удалить @RequestBody
аннотацию к параметру метода
// removed @RequestBody annotation
public Map login(AdminLogin parameters) {
// .... body
}
Вам нужно будет использовать RequestParam
аннотацию и изменить свой метод следующим образом
// using map to get all the keys amp; their values.
public Map login(@RequestParam Map<String, String> map){
}
// get all the form parameter in separate method parameter like so
// (key name are dummies here, use appropriate names when using)
public Map login(@RequestParam("key1") String key1, @RequestParam("key2") String key2){
}
Я также думаю, что раздел параметров headers
with Accept
здесь не нужен.
Изображение, показывающее API, вызываемый с помощью клиента Postman (игнорируйте URL здесь… просто тестирование)
Изображение, показывающее значение, полученное на карте. Обратите внимание на данные, отправленные в вызове API, и данные, полученные в объекте map.
Комментарии:
1. Если я удалю аннотацию @RequestBody, она начнет работать, но тогда я не смогу извлечь значения из параметров. Это дает NullPointerExpection
2. Можете ли вы предложить решение, пожалуйста?
3. Я обновил код. Отправленные параметры могут быть зафиксированы либо в map, либо в параметрах отдельного метода. Я не смог получить значения в пользовательском классе. Попробую позже.
4. Спасибо, но @RequestParam не может получить параметры метода POST. Если мне нравится эта карта, выдается null.get(‘username’)
5. @Ravinder, если этот ответ помогает и работает для вас, пожалуйста, отметьте его как ответ.