HTTP 的 Get/Post/Delete/Put
對應到 Resource 的 CRUD (Create, Retrieve, Update and Delete)
,其中 POST 和 PUT 最常讓人摸不著頭緒,不知道什麼時候該用什麼。
今天 survey 了一下網路的資料,大概可以歸納出如下兩張圖,未來在遇到相關的設計時可以參照琢磨琢磨。
HTTP 的 Get/Post/Delete/Put
對應到 Resource 的 CRUD (Create, Retrieve, Update and Delete)
,其中 POST 和 PUT 最常讓人摸不著頭緒,不知道什麼時候該用什麼。
今天 survey 了一下網路的資料,大概可以歸納出如下兩張圖,未來在遇到相關的設計時可以參照琢磨琢磨。
Let's say, the original method to access the openfire service by http is by HttpServlet (ex. presence plugin). So, how to replace it with Jersey for convenient development? In this post, I will detail the steps and the problems I met during achieving this.
The main reference is here. Assuming that you have successfully run a self-made plugin.
web-custom.xml
The web-custom.xml
tells the container where to search for resource class. From
that reference. There is some tricks in the web-custom.xml processing in openfire.
So we need a wrapper, and finding the true resource class package there. As below. The class in the <servlet-class>
tag is your wrapper class, the
path in <url-pattern>
is the base url you want.
<!-- Servlets --> <servlet> <servlet-name>BrownyServlet</servlet-name> <servlet-class>com.brownylin.openfire.plugin.browny.BrownyServletWrapper</servlet-class> </servlet> <!-- Servlet mappings --> <servlet-mapping> <servlet-name>BrownyServlet</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping>
The trick in the wrapper class is to find resouce class by PackagesResourceConfig
.
Below sample is referenced from that link.
The resouce class should be under the same package (or inner) as the wrapper class.
AuthCheckFilter.addExclude(SERVLET_URL);
is used for avoiding the need of login to access
the api.
public class BrownyServletWrapper extends ServletContainer { private static final long serialVersionUID = 1L; private static final String SERVLET_URL = "browny/test/*"; private static final String SCAN_PACKAGE_KEY = "com.sun.jersey.config.property.packages"; private static final String SCAN_PACKAGE_DEFAULT = BrownyServletWrapper.class .getPackage().getName(); private static final String RESOURCE_CONFIG_CLASS_KEY = "com.sun.jersey.config.property.resourceConfigClass"; private static final String RESOURCE_CONFIG_CLASS = "com.sun.jersey.api.core.PackagesResourceConfig"; private static Map<String, Object> config; private static PackagesResourceConfig prc; static { config = new HashMap<String, Object>(); config.put(RESOURCE_CONFIG_CLASS_KEY, RESOURCE_CONFIG_CLASS); config.put(SCAN_PACKAGE_KEY, SCAN_PACKAGE_DEFAULT); prc = new PackagesResourceConfig(SCAN_PACKAGE_DEFAULT); prc.setPropertiesAndFeatures(config); prc.getClasses().add(BrownyResources.class); } public BrownyServletWrapper() { super(prc); } @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); // Exclude this servlet from requering the user to login AuthCheckFilter.addExclude(SERVLET_URL); } @Override public void destroy() { super.destroy(); // Release the excluded URL AuthCheckFilter.removeExclude(SERVLET_URL); } }
They are asm-3.3.1.jar
, jersey-bundle-1.10-b01.jar
, jersey-servlet-1.17.1.jar
, jsr311-api-1.1.1.jar
. If wrong dependency, the ClassNotFoundException
, ClassNotDefException
will happen (you could find the error from openfire_src/target/openfire/logs/error.log
)
The trick here is the @Path()
should starts from plugin name, later servlet url-pattern and at the end - path of the your resouce. So that is @Path("browny/test/hello")
package com.brownylin.openfire.plugin.browny; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("browny/test/hello") public class BrownyResources { @GET @Path("/") public Response getMsg() { String output = "Jersey say Hello"; return Response.status(200).entity(output).build(); } }
As this thread said. The default configuration is to capture all text/html content from the server and force it into the admin page.
You could add the url pattern you want to exclude in openfire_src/src/web/WEB-INF/decorators.xml
as below
<decorators defaultdir="/decorators"> <decorator name="setup" page="setup.jsp"> <pattern>/setup/*.jsp</pattern> </decorator> <decorator name="main" page="main.jsp"> <pattern>/*.jsp</pattern> <pattern>/plugins</pattern> </decorator> <decorator name="none"/> <excludes> <pattern>/setup/setup-completed.jsp*</pattern> <pattern>/setup/setup-ldap-server_test.jsp*</pattern> <pattern>/setup/setup-ldap-user_test.jsp*</pattern> <pattern>/setup/setup-ldap-group_test.jsp*</pattern> <pattern>/setup/setup-clearspace-integration_test.jsp*</pattern> <pattern>/setup/setup-admin-settings_test.jsp*</pattern> <pattern>/login.jsp*</pattern> <pattern>/plugin-icon.jsp*</pattern> <pattern>/js/jscalendar/i18n.jsp*</pattern> <pattern>/plugins/browny/test/*</pattern> </excludes> </decorators>
Last, test the url localhost:9090/plugins/browny/test/hello
. It's done. Hope this will be useful to someone :)
-- EOF --