Как исправить неподдерживаемый тип носителя 415 для Rest API между Angular 7 и Java

#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, если этот ответ помогает и работает для вас, пожалуйста, отметьте его как ответ.