Angular: HttpErrorResponse: сбой HTTP во время синтаксического анализа для строки, успешно возвращаемой с сервера

Spring-boot на стороне сервера RESTful; метод тестирования, который вернет строку:

@RequestMapping(value = "test", method = RequestMethod.GET)
    public ResponseEntity<String> test(HttpServletRequest req, HttpServletResponse resp) {
        try {
            return new ResponseEntity<String>("Test has worked, biatch!", HttpStatus.OK);
        } catch (Exception e) {
            System.err.println("## EXCEPTION: " + e.getMessage());
            return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }

от Postman - все работает отлично, и я получаю правильно проанализированную строку из JSON.

Однако, когда я пытаюсь сделать то же самое с моей клиентской стороны Angular, я продолжаю получать сгенерированный объект HttpErrorResponse.

  public url: string = "http://localhost:8080/theater/admin/test";
  constructor(private as: AdminService, private http: HttpClient) { }

  ngOnInit() {
  }

  getTest() {
    this.as.getTest()
      .subscribe(data => console.log(data), // this should happen on success
        error => console.log(error));  // this should happen on error
  }

как ни странно, он содержит строку, возвращенную с сервера, и я могу получить к ней доступ с помощью error.text в функции подписки. объект Error на консоли:

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:8080/theater/admin/test", ok: false, …}
error
:
{error: SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "Test has worked, biatch!"}
headers
:
HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message
:
"Http failure during parsing for http://localhost:8080/theater/admin/test"
name
:
"HttpErrorResponse"
ok
:
false
status
:
200
statusText
:
"OK"
url
:
"http://localhost:8080/theater/admin/test"
__proto__
:
HttpResponseBase

Возможно, это связано с синтаксическим анализом возвращаемого с сервера объекта JSON, содержащего строку. тем не менее, возвращая объекты, коллекции и все остальное - работает совершенно нормально - .subscribe() правильно анализирует любые объекты, которые я получаю с сервера, или, если на сервере произошло исключение, возвращенный HttpStatus правильно вызывает HttpErrorResponse на стороне клиента.

Итак, что случилось со строками, которые дают осечку? Я всегда получаю HttpErrorResponse, несмотря ни на что. я делаю что-то неправильно здесь?


person Maoration    schedule 12.09.2018    source источник
comment
JSON имеет неверный формат. Вероятно, это вообще не JSON   -  person Antoniossss    schedule 12.09.2018
comment
Итак, как я должен обрабатывать это по-другому на стороне клиента?   -  person Maoration    schedule 12.09.2018


Ответы (3)


Тест сработал, сука!

Это не JSON. Таким образом, ошибка синтаксического анализа.

Вероятно, это связано с анализом возвращаемого с сервера объекта JSON, содержащего строку. однако возврат объектов, коллекций и всего остального работает отлично - .subscribe()

Ну, это сработало для POJO, потому что они закодированы в JSON. Здесь у вас есть простой String

Чтобы получить ответ в виде строки вместо объекта, сделайте что-то вроде

 http.get(url, {responseType: 'text'})
person Antoniossss    schedule 12.09.2018
comment
Итак, как я должен обрабатывать это по-другому на стороне клиента? - person Maoration; 12.09.2018
comment
Попробуйте http.get(url, {responseType: text'} - person Antoniossss; 12.09.2018
comment
Прочитав этот ответ, я также нашел его в документации: https://angular.io/guide/http#requesting-non-json-data - person yasd; 19.12.2019

Попробуйте что-то вроде этого -

{ responseType: 'text' as 'json' }

Я столкнулся с той же проблемой с HttpClient в Angular 7, которая была решена с помощью вышеуказанной настройки.

Проблема заключается в том, что вы используете тип возвращаемого значения для get или post или любого метода из httpClient, например:

this.http.get<FooClass>(url)

Он предполагает, что тип ответа — JSON, и поэтому ожидает в ответ объект JSON. Установка типа ответа как «текст» в качестве «json» приведет к принудительному текстовому ответу.

person Rajesh Panda    schedule 07.02.2019
comment
Я пробовал много способов, и это единственный, который работал. - person ; 29.10.2020

Я решил эту проблему, используя JsonObject для правильного построения строки JSON, которая затем вставляется в ResponseEntity:

@PostMapping(...)
public ResponseEntity handler(HttpServletRequest req, HttpServletResponse resp) {
  JsonObjectBuilder builder = Json.createObjectBuilder();
  builder.add("text", "Hello World!");
  JsonObject json = builder.build();

  return new ResponseEntity<>(json.toString(), HttpStatus.OK);
}

person loroz    schedule 21.03.2019