implementing-reflection.rst 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. .. _rest_services_implementing_reflection:
  2. Implementing a RESTful Service with Reflection
  3. ==============================================
  4. The previous section showed how to save some effort when implementing a
  5. RESTful service by taking advantage of the ``MapResource`` base class. This section will show how to make use of a different base class, but for a
  6. similar purpose.
  7. The class used is ``org.geoserver.rest.ReflectiveResource``. The idea with
  8. ``ReflectiveResource`` is that a resource is backed by an arbitrary object.
  9. The ``ReflectiveResource`` class uses reflection to automatically create
  10. representations of the resource as XML or JSON.
  11. Prerequisites
  12. --------------
  13. This section builds off the example in the previous section
  14. :ref:`rest_services_implementing_map`.
  15. Create a new java bean
  16. ----------------------
  17. #. The use of ``ReflectiveResource`` requires we have an underlying object to
  18. to work with. Create a class named ``Hello`` in the package
  19. ``org.geoserver.hellorest``:
  20. .. code-block:: java
  21. package org.geoserver.hellorest;
  22. public class Hello {
  23. String message;
  24. public Hello( String message ) {
  25. this.message = message;
  26. }
  27. public String getMessage() {
  28. return message;
  29. }
  30. }
  31. Create a new resource class
  32. ---------------------------
  33. #. Create a new class called ``HelloReflectiveResource`` in the package
  34. ``org.geoserver.hellorest``, which extends from ``ReflectiveResource``:
  35. .. code-block:: java
  36. package org.geoserver.hellorest;
  37. import org.geoserver.rest.ReflectiveResource;
  38. public class HelloReflectiveResource extends ReflectiveResource {
  39. @Override
  40. protected Object handleObjectGet() throws Exception {
  41. return null;
  42. }
  43. }
  44. #. The first method to implement is ``handleObjectGet()``. The purpose of this
  45. method is to return the underlying object representing the resource. In
  46. this case, an instance of the ``Hello`` class created in the previous step.
  47. .. code-block:: java
  48. @Override
  49. protected Object handleObjectGet() throws Exception {
  50. return new Hello( "Hello World" );
  51. }
  52. Update the application context
  53. ------------------------------
  54. #. The next step is to update an application context and tell GeoServer
  55. about the new resource created in the previous section. Update the
  56. ``applicationContext.xml`` file so that it looks like the following:
  57. .. code-block:: xml
  58. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  59. <beans>
  60. <bean id="hello" class="org.geoserver.hellorest.HelloResource"/>
  61. <bean id="helloMap" class="org.geoserver.hellorest.HelloMapResource"/>
  62. <bean id="helloReflective" class="org.geoserver.hellorest.HelloReflectiveResource"/>
  63. <bean id="helloMapping" class="org.geoserver.rest.RESTMapping">
  64. <property name="routes">
  65. <map>
  66. <entry>
  67. <key><value>/hello.{format}</value></key>
  68. <!--value>hello</value-->
  69. <!--value>helloMap</value-->
  70. <value>helloReflective</value>
  71. </entry>
  72. </map>
  73. </property>
  74. </bean>
  75. </beans>
  76. There are two things to note above. The first is the addition of the
  77. ``helloReflective`` bean. The second is a change to the ``helloMapping``
  78. bean, which now maps to the ``helloReflective`` bean.
  79. Test
  80. ----
  81. #. Create a new test class called ``HelloReflectiveResourceTest`` in the
  82. package ``org.geoserver.hellorest``, which extends from
  83. ``org.geoserver.test.GeoServerTestSupport``:
  84. .. code-block:: java
  85. package org.geoserver.hellorest;
  86. import org.geoserver.test.GeoServerTestSupport;
  87. public class HelloReflectiveResourceTest extends GeoServerTestSupport {
  88. }
  89. #. Add a test named ``testGetAsXML()`` which makes a GET request for
  90. ``/rest/hello.xml``:
  91. .. code-block:: java
  92. ...
  93. import org.w3c.dom.Document;
  94. import org.w3c.dom.Node;
  95. ...
  96. public void testGetAsXML() throws Exception {
  97. //make the request, parsing the result as a dom
  98. Document dom = getAsDOM( "/rest/hello.xml" );
  99. //print out the result
  100. print(dom);
  101. //make assertions
  102. Node message = getFirstElementByTagName( dom, "message");
  103. assertNotNull(message);
  104. assertEquals( "Hello World", message.getFirstChild().getNodeValue() );
  105. }
  106. #. Add a second test named ``testGetAsJSON()`` which makes a GET request
  107. for ``/rest/hello.json``:
  108. .. code-block:: java
  109. ...
  110. import net.sf.json.JSON;
  111. import net.sf.json.JSONObject;
  112. ...
  113. public void testGetAsJSON() throws Exception {
  114. //make the request, parsing the result into a json object
  115. JSON json = getAsJSON( "/rest/hello.json");
  116. //print out the result
  117. print(json);
  118. //make assertions
  119. assertTrue( json instanceof JSONObject );
  120. JSONObject hello = ((JSONObject) json).getJSONObject( "org.geoserver.hellorest.Hello" );
  121. assertEquals( "Hello World", hello.get( "message" ) );
  122. }
  123. #. Build and test the ``hello_test`` module::
  124. [hello_rest]% mvn clean install -Dtest=HelloMapReflectiveResourceTest