Недавно я писал о том, как использовать
привязку JSON EclipseLink JAXB (MOXy) для создания службы RESTful. В этой статье я покажу, как легко использовать преимущества JSON-связывания MOXy на стороне клиента.
- MOXy как ваш JAX-RS JSON-провайдер — на стороне сервера
- MOXy как ваш JAX-RS JSON-провайдер — на стороне клиента
Этот пост будет посвящен следующему URI от сервиса, который мы объявили в
предыдущем посте
. Следующий звонок вернет список клиентов, которые живут в «Любом городе».
В первом примере мы будем использовать стандартные API Java SE 6. Некоторые интересные вещи, чтобы отметить:
- MOXy может непосредственно маршалировать (строка 35) и демаршалировать (строка 28) коллекции в / из массивов JSON без необходимости использования объекта-оболочки.
- На MOXy нет зависимостей времени компиляции (это зависимость времени выполнения).
- Свойство eclipselink.media-type используется для включения привязки JSON для демаршаллера (строка 25) и маршаллера (строка 33).
- Свойство eclipselink.json.include-root используется для указания того, что аннотация @XmlRootElement должна игнорироваться в привязке JSON (строки 26 и 34).
package example; import java.io.InputStream; import java.net.*; import java.util.List; import javax.xml.bind.*; import javax.xml.transform.stream.StreamSource; import org.example.Customer; public class JavaSEClient { private static final String MEDIA_TYPE = "application/json"; public static void main(String[] args) throws Exception { String uri = "http://localhost:8080/CustomerService/rest/customers/findCustomersByCity/Any%20Town"; URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", MEDIA_TYPE); JAXBContext jc = JAXBContext.newInstance(Customer.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshaller.setProperty("eclipselink.media-type", MEDIA_TYPE); unmarshaller.setProperty("eclipselink.json.include-root", false); InputStream xml = connection.getInputStream(); List<Customer> customers = (List<Customer>) unmarshaller.unmarshal(new StreamSource(xml), Customer.class).getValue(); connection.disconnect(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty("eclipselink.media-type", MEDIA_TYPE); marshaller.setProperty("eclipselink.json.include-root", false); marshaller.marshal(customers, System.out); } }
Ниже приведены результаты работы клиента Java SE. Для тех, кто мог использовать реализацию JAXB (
JSR-222 ) с чем-то вроде
Jettison для производства / потребления JSON, вот несколько интересных моментов , на которые следует обратить внимание:
- MOXy отображает коллекции в виде массивов JSON.
- MOXy правильно представляет числовые значения без кавычек (строка 26).
- MOXy правильно окружает коллекции размера 1 квадратными скобками (строки 28 и 32).
[ { "address" : { "city" : "Any Town", "id" : 1, "street" : "1 A Street" }, "firstName" : "Jane", "id" : 1, "lastName" : "Doe", "phoneNumbers" : [ { "id" : 2, "num" : "555-2222", "type" : "HOME" }, { "id" : 1, "num" : "555-1111", "type" : "WORK" } ] }, { "address" : { "city" : "Any Town", "id" : 10, "street" : "456 Another Road" }, "firstName" : "Sue", "id" : 10, "lastName" : "Jones", "phoneNumbers" : [ { "id" : 10, "num" : "555-3333", "type" : "WORK" } ] } ]
JAX-RS 2.0 (
JSR-339
) работает над стандартизацией клиентских API. С JAX-RS 1.0 многие реализации предоставляют свою собственную версию. Ниже приведен пример использования клиентских API, предоставленных
Jersey
. Обратите внимание, как мы можем использовать точно такой же
MessageBodyReader
/
Writer,
который мы использовали на стороне сервера (строка 14,
обозначьте MOXy как Ваш JSON-поставщик JAX-RS — Сторона сервера
). Я также указал LoggingFilter (строка 17), чтобы мы могли более внимательно посмотреть на сообщение.
package example; import java.util.List; import org.example.Customer; import org.example.MOXyJSONProvider; import com.sun.jersey.api.client.*; import com.sun.jersey.api.client.config.*; import com.sun.jersey.api.client.filter.LoggingFilter; public class JerseyClient { public static void main(String[] args) { ClientConfig cc = new DefaultClientConfig(); cc.getClasses().add(MOXyJSONProvider.class); Client client = Client.create(cc); client.addFilter(new LoggingFilter()); WebResource resource = client.resource("http://localhost:8080/CustomerService/rest/customers"); List<Customer> customers = resource.path("/findCustomersByCity/Any%20Town").accept("application/json").get(new GenericType<List<Customer>>(){}); for(Customer customer : customers) { System.out.println(customer.getFirstName()); } } }
Ниже приведен результат запуска клиента Джерси.
14-Mar-2012 4:08:12 PM com.sun.jersey.api.client.filter.LoggingFilter log INFO: 1 * Client out-bound request 1 > GET http://localhost:8080/CustomerService/rest/customers/findCustomersByCity/Any%20Town 1 > Accept: application/json 1 > 14-Mar-2012 4:08:12 PM com.sun.jersey.api.client.filter.LoggingFilter log INFO: 1 * Client in-bound response 1 < 200 1 < Transfer-Encoding: chunked 1 < Date: Wed, 14 Mar 2012 20:08:12 GMT 1 < Content-Type: application/json 1 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.1 Java/Oracle Corporation/1.7) 1 < Server: GlassFish Server Open Source Edition 3.1.1 1 < [{"address" : {"city" : "Any Town", "id" : 1, "street" : "1 A Street"}, "firstName" : "Jane", "id" : 1, "lastName" : "Doe", "phoneNumbers" : [{"id" : 1, "num" : "555-1111", "type" : "WORK"}, {"id" : 2, "num" : "555-2222", "type" : "HOME"}]}, {"address" : {"city" : "Any Town", "id" : 10, "street" : "456 Another Road"}, "firstName" : "Sue", "id" : 10, "lastName" : "Jones", "phoneNumbers" : [{"id" : 10, "num" : "555-3333", "type" : "WORK"}]}] Doe, Jane Jones, Sue