Spring Ajax @ResponseBody ze zwracanymi wartościami null


Mam około pięćdziesięciu kontrolerów, które używają adnotacji @ResponseBody.
Podobne do tego:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
public @ResponseBody Object getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
return object;
}

Kilkakrotnie metoda getObject zwraca
null
. Problem w tym, że po stronie klienta dostaję

pusta odpowiedź

Zamiast null .
We wstępnej implementacji mamy niestandardowy obiekt
JsonView
, który działa jak opakowanie bez adnotacji @ResponseBody.
Podobne do tego:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
public JsonView<Object> getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
return new JsonView(object);
}

Więc wszystko poszło dobrze.
Znalazłem rozwiązanie w

Jak zastąpić zerowy serializator w Jackson 2.0?
https://coderoad.ru/18101506/
ale niestety działa to tylko dla pól w POJO.
Czy masz jakieś pomysły, jak sobie z tym poradzić?
Z góry dziękuję!
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie jest to prosty problem do rozwiązania.
Spring ma wspólny wzorzec, że jeśli metoda obsługi zwraca
null
, oznacza to, że procedura obsługi już zajęła się tworzeniem i pisaniem odpowiedniej treści odpowiedzi i nie jest wymagana żadna dalsza akcja na froncie.
Spring zaimplementował ten wzorzec w swojej implementacji
RequestResponseBodyMethodProcesser
(
HandlerMethodReturnValueHandler
dla
@ResponseBody
). sprawdza, czy zwrócona wartość to
null
. Ustawia żądanie jako przetworzone. Jeśli zwracana wartość nie jest
null
, próbuje serializować ją za pomocą odpowiedniego
HttpMessageConverter
.
Jedną z opcji jest utworzenie własnej adnotacji
@ResponseBodyNull
i odpowiedniej adnotacji
HandlerMethodReturnValueHandler
, która robi to samo, ale obsługuje również
null
. Pamiętaj, że niekoniecznie możesz ponownie użyć kodu z
RequestResponseBodyMethodProcess
, ponieważ niektóre
HttpMessageConverters
nie powiodą się podczas próby użycia
null
.
Inną podobną opcją jest zastąpienie
REQUESTRESSONEBUTYMETODProcessor
, aby zrobić
NULL
(z powyższymi ograniczeniami) i zarejestruj go wyraźnie z
RequestMappingHandlermancing
, nadpisanie domyślnie Kod> HandlermethodReturnvalueHandler s. Musisz to zrobić uważnie (tj. Zarejestruj się tak samo), chyba że chcesz stracić funkcjonalność.
Najlepszym rozwiązaniem, IMO, byłoby nie zajmowanie się
null
w treści odpowiedzi. Jeśli
getObject
nic nie zwraca, wygląda to na 404. Ustaw odpowiedni kod odpowiedzi i voila!
Zawsze możesz wstrzyknąć
HttpServletResponse
do swojej metody obsługi i zrobić coś w rodzaju
Object object = getObject(..);
if (object == null) {
response.getWriter().print("null");
// also set the content type to application/json
}
return object;

Zakładając, że wiesz, że powinno to zostać serializowane do formatu JSON.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz zwrócić ResponseEntity i określić stan HTTP dla błędu, gdy obiekt ma wartość null:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
public ResponseEntity<Object> getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
if (object == null ) {
return new ResponseEntity<Object> (HttpStatus.BAD_REQUEST);// Or any other error status
} else {
return new ResponseEntity<Object> (object, HttpStatus.OK);
}
}

W ten sposób Twój klient będzie mógł wiedzieć, kiedy pusty obiekt sprawdza stan odpowiedzi.
Jeśli naprawdę chcesz mieć wartość zwracaną null, możesz skonfigurować Jacksona, aby ją serializował (kod z

tkuty
https://stackoverflow.com/a/13876694/1979824
):
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion">
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

Mam nadzieję, że to ci pomoże.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Po pierwsze, radzę, abyś nie napisać tego:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
public @ResponseBody Object getObject(@RequestParam("id") Long id) {
/*
*/
}

Zrób to jako standardowy kod. Spróbuj:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
@ResponseBody
public Object getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
return object;
}

Mam doświadczenie z wysokiej jakości skanera, ten sposób pomoże uniknąć błędów wykrytych przez skaner. Jeśli chodzi o problem, możesz spróbować Transformer lub AddsCala (), aby zamiast tego wrócić POJO. Pobiegłem do tego nieszczęścia i umawiałem! Powodzenia.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się