java - 如何将 FlightOfferSearch 和 FlightOrder 对象作为 JSON 返回?
问题描述
如果我尝试从我的 Spring Boot REST 控制器的处理程序方法返回 FlightOfferSearch[] 或 FlightOrder 对象,它们似乎并没有像我之前使用过的更简单的 POJO 那样正确序列化,其中 Jackson 处理 JSON 序列化。
我的代码(实际 API 调用与SDK github 示例大体相同):
import com.amadeus.Amadeus;
import com.amadeus.Params;
import com.amadeus.exceptions.ResponseException;
import com.amadeus.resources.FlightOfferSearch;
import com.amadeus.resources.FlightOrder;
import com.amadeus.resources.Traveler;
import io.github.cdimascio.dotenv.Dotenv;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@RequestMapping("api/v1")
@RestController
public class TestController {
private static Amadeus getFreshAccessToken() {
Dotenv dotenv = Dotenv.load();
return Amadeus
.builder(Objects.requireNonNull(dotenv.get("AMADEUS_KEY")), Objects.requireNonNull(dotenv.get("AMADEUS_SECRET")))
.build();
}
@GetMapping("/test")
FlightOrder testHandler() throws ResponseException {
Amadeus amadeus = getFreshAccessToken();
Traveler traveler = new Traveler();
traveler.setId("1");
traveler.setDateOfBirth("2000-04-14");
traveler.setName(traveler.new Name("JORGE", "GONZALES"));
Traveler.Phone[] phone = new Traveler.Phone[1];
phone[0] = traveler.new Phone();
phone[0].setCountryCallingCode("33");
phone[0].setNumber("675426222");
phone[0].setDeviceType("MOBILE");
Traveler.Contact contact = traveler.new Contact();
contact.setPhones(phone);
traveler.setContact(contact);
Traveler.Document[] document = new Traveler.Document[1];
document[0] = traveler.new Document();
document[0].setDocumentType("PASSPORT");
document[0].setNumber("480080076");
document[0].setExpiryDate("2022-10-11");
document[0].setIssuanceCountry("ES");
document[0].setNationality("ES");
document[0].setHolder(true);
traveler.setDocuments(document);
Traveler[] travelerArray = new Traveler[1];
travelerArray[0] = traveler;
System.out.println(travelerArray[0]);
FlightOfferSearch[] flightOffersSearches = amadeus.shopping.flightOffersSearch.get(
Params.with("originLocationCode", "SYD")
.and("destinationLocationCode", "BKK")
.and("departureDate", "2020-11-01")
.and("returnDate", "2020-11-08")
.and("adults", 1)
.and("max", 1));
FlightOrder order = amadeus.booking.flightOrders.post(flightOffersSearches, travelerArray);
return order;
}
}
邮递员请求返回:
"status": 500,
"error": "Internal Server Error",
"message": "JSON mapping problem: com.amadeus.resources.FlightOrder[\"response\"]->com.amadeus.Response[\"result\"]->com.google.gson.JsonObject[\"asBoolean\"]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: JsonObject (through reference chain: com.amadeus.resources.FlightOrder[\"response\"]->com.amadeus.Response[\"result\"]->com.google.gson.JsonObject[\"asBoolean\"])",
和服务器日志
ERROR 45864 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: JSON mapping problem: com.amadeus.resources.FlightOrder["response"]->com.amadeus.Response["result"]->com.google.gson.JsonObject["asBoolean"]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: JsonObject (through reference chain: com.amadeus.resources.FlightOrder["response"]->com.amadeus.Response["result"]->com.google.gson.JsonObject["asBoolean"])] with root cause
java.lang.UnsupportedOperationException: JsonObject
at com.google.gson.JsonElement.getAsBoolean(JsonElement.java:153) ~[gson-2.8.5.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_232]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_232]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_232]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_232]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1433) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:921) ~[jackson-databind-2.10.2.jar:2.10.2]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:294) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:287) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) [tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.31.jar:9.0.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_232]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.31.jar:9.0.31]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_232]
我还需要做些什么来将它们转换为 JSON 格式吗?
解决方案
我重新编写了 Java SDK 助手来修复和添加一些东西:
- 修复试图预订搜索的所有航班的错误。
- 添加了一种新方法,允许您使用单个 FlightOfferSearch(不是数组)进行预订
- 我添加了一个从 FlightPrice 对象预订的方法。理论上,您不应该直接从 FlightOfferSearch 预订,您应该在预订前调用 Flight Offers Price API 来确认价格和可用性。你可以在这里找到一个例子。您可以在本教程中了解有关航班预订流程的更多信息。
供您参考,如果我们的任何助手失败,我们所有的 API 都支持带有 JSON 直接(在 String 或 JsonObject 中)的帖子,您可以使用该方法(获取您的对象,在 String/JSON 中反序列化并直接使用它)。
我发布了新版本的SDK版本4.1.0
请更新到这个版本。
推荐阅读
- r - R Drake - 将 make() 配置为根本不使用缓存
- javascript - 断开连接后,Socket.io 不会从数组中删除用户对象
- node.js - 将 webpack 设置为 --host 0.0.0.0 不起作用
- hbase - 无法在 Mac OS 上启动 hbase
- c# - Unity3d Android/Windows 应用程序与库的集成
- apache-spark - ^M 添加到火花输出中
- scala - 将两个数组合并为 jsonObjects 数组
- .net - Angular POST 请求响应为空(但服务器返回正确的字符串)
- lua - 有没有办法使用 lua 使用 ESP NOW 协议?
- node.js - 使用 Gun 构建树结构