Я использую Jackson для интерпретации ответов JSON от API, который я пишу. Я хотел бы, в качестве стандарта на протяжении всей моей API, чтобы бросить ошибки из API в программе что-то вроде:Пустой ответ JSON не вызывает ошибку в Jackson
{"errorMessage":"No such username."}
Так что я хочу, чтобы мой процессор ответ сначала проверить, является ли ответ только один ключ ErrorMessage, и если да, то обрабатывать ошибку, а если нет, то интерпретировать ее как любой ответ, который он ожидал от этой команды.
Так вот мой код:
public class ProcessingException extends Exception {
private String errorMessage;
public ProcessingException(){}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
, а затем, на мой обработчик ответа:
@Override
public void useResponse(InputStream in) throws IOException, ProcessingException {
// turn response into a string
java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
String response = s.hasNext() ? s.next() : "";
ProcessingException exception;
try {
// Attempt to interpret as an exception
exception = mapper.readValue(response, ProcessingException.class);
}
catch(IOException e) {
// Otherwise interpret it as expected. responseType() is an abstract TypeReference
// which is filled in by subclasses. useResponse() is also abstract. Each subclass
// represents a different kind of request.
Object responseObj = mapper.readValue(response, responseType());
useResponse(responseObj);
return;
}
// I needed this out of the try/catch clause because listener.errorResponse might
// actually choose to throw the passed exception to be dealt with by a higher
// authority.
if (listener!=null) listener.errorResponse(exception);
}
Это прекрасно работает, за исключением случаев, одно обстоятельство - есть некоторые запросы, которые на самом деле не нужно ответить на что-нибудь, поэтому они возвращают {}
. По какой-то причине этот ответ полностью проходит через строку exception = mapper.readValue(response, ProcessingException.class);
, не вызывая исключение IOException, поэтому в программе происходят ошибки. Но затем, когда он пытается прочитать, что это за ошибка, он бросает NullPointerException
при попытке прочитать exception.getErrorMessage()
, потому что, конечно, ошибок нет.
Почему он обрабатывает {}
как действительный ProcessingException
объект?
Мысли вслух себе - может быть, он думает, что пустой конструктор является допустимым способом построения ответа? – clum
Почему вы не используете коды состояния, чтобы указать, когда в запросе была ошибка? В качестве примера, возврат 400 будет означать, что ответное сообщение должно рассматриваться как «ОбработкаException». –
И да, @clum прав. Json без свойств определенно является допустимым способом построения «ProcessingException» –