浏览 2737 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-02-14
restful一直很火热,而且由restful提供出的resource非常轻便快捷。 我是在研究spring mvc和activiti5的过程中逐渐接触到restful的,尤其在修改activiti5源码的时候觉得activiti5使用的restlet非常轻便,配置文件也很简洁。 所以当我们项目组在监控activeMQ的queue时我就想能不能把activeMQ的队列信息暴露出来,供我们的监控接口实时进行监控呢。后来下了activeMQ-5.2.0的源码之后发现activeMQ所有的资源信息都已经加载到spring环境中了,有了spring这么熟悉的框架的帮助下要做的事情就变得非常清晰了。 把重点放在activeMQ项目下的activemq-web-console这个子项目上。(访问http://localhost:8161/admin其实就是访问的这个web应用)首先在classpath下加入以下几个restlet的jar包:org.restlet.ext.fileupload-2.0.8.jar,org.restlet.ext.jackson-2.0.8.jar,org.restlet.ext.servlet-2.0.8.jar,org.restlet-2.0.8.jar。 restlet的环境就已经准备好了,然后在web.xml中加入restlet的servlet配置(所有*/service/*的请求就都会由这个servlet进行分发了): <!-- restlet --> <servlet> <servlet-name>RestletServlet</servlet-name> <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class> <init-param> <!-- Application class name --> <param-name>org.restlet.application</param-name> <param-value>org.apache.activemq.web.restful.ActiveMqRestApplication</param-value> </init-param> </servlet> <!-- Catch all requests --> <servlet-mapping> <servlet-name>RestletServlet</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> 当然'org.apache.activemq.web.restful'这个目录是我新建的,所以接下来我们要在这个新建的目录下编写ActiveMqRestApplication。 import org.restlet.Application; import org.restlet.Restlet; import org.restlet.data.ChallengeScheme; import org.restlet.routing.Router; import org.restlet.security.ChallengeAuthenticator; import org.restlet.security.SecretVerifier; import org.restlet.security.Verifier; public class ActiveMqRestApplication extends Application { private ChallengeAuthenticator authenticator; @Override public synchronized Restlet createInboundRoot() { Verifier verifier = new SecretVerifier() { @Override public boolean verify(String username, char[] password){ return true; } }; authenticator = new ChallengeAuthenticator(null, true,ChallengeScheme.HTTP_BASIC, "ActiveMQ Realm",verifier); Router router = new Router(getContext()); router.attach("/comsumers/{queueName}", ConsumersResource.class); authenticator.setNext(router); return authenticator; } } 所有想要暴露的资源都按照以上形式attach到router中即可。我现在暴露了一个查看某队列所有consumers数量的资源。 接下来就要编写ConsumersResource类了: import org.apache.activemq.broker.jmx.QueueViewMBean; import org.apache.activemq.web.LocalBrokerFacade; import org.restlet.representation.Representation; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; import org.springframework.context.ApplicationContext; public class ConsumersResource extends ServerResource { @Get public String getConsumerCount(Representation entity) { try { String queueName = (String) getRequest().getAttributes().get("queueName"); ApplicationContext context = RestfulApplicationContextUtil.getContext(); LocalBrokerFacade brokerQuery = (LocalBrokerFacade)context.getBean("brokerQuery"); QueueViewMBean queue = brokerQuery.getQueue(queueName); if (queue != null){ return queue.getConsumerCount() + ""; }else { return "-1"; } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("检测队列消费者时出错"); } } } 这个类就是通过get请求根据queueName查找这个queue的consumers的数量,然后返回字符串 这里的RestfulApplicationContextUtil是自己写的一个工具类,用于能把spring环境中管理的bean拿出来在非spring环境中使用,其实就是一个静态方法调出web工程中的spring环境。 import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class RestfulApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext;// 声明一个静态变量保存 public static ApplicationContext getContext() { return applicationContext; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } } 然后把这个工具类放到spring环境里,我图省事就但写了一个spring的配置文件springUtil.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <bean id ="restfulApplicationContextUtil" class="org.apache.activemq.web.restful.RestfulApplicationContextUtil"></bean> </beans> 最后一步就是找到这个web工程加载默认环境的初始化类中的初始化方法(用的默认的数据源配置,并没有把消息信息进行持久化) WebConsoleStarter类的createWebapplicationContext()方法,在加载configuration时捎带手的把新建的springUtil.xml也加载进去: private WebApplicationContext createWebapplicationContext(ServletContext servletContext) { String webconsoleType = System.getProperty("webconsole.type", "embedded"); String configuration = "/WEB-INF/webconsole-" + webconsoleType + ".xml"; XmlWebApplicationContext context = new XmlWebApplicationContext(); context.setServletContext(servletContext); context.setConfigLocations(new String[] { configuration, "/WEB-INF/springUtil.xml" }); context.refresh(); context.start(); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context); return context; } 由于activemq用的web容器是jetty,我对jetty一点也不熟,所以就没有在eclipse里进行部署和测试,不过把那4个restlet的jar包扔到apache-activemq-5.2.0\lib目录下,编译过后的.class文件按相应目录结构扔到apache-activemq-5.2.0\webapps\admin之后启动访问 http://localhost:8161/admin/service/comsumers/MyQueue这个地址就能获得MyQueue这个队列的consumers的数量了。 用restlet客户端调用也非常简单,首先把restlet环境加进去(那4个jar包),具体代码就两行: import org.restlet.resource.ClientResource; ClientResource cr = new ClientResource("http://localhost:8161/admin/service/comsumers/MyQueue"); String resultStr = cr.get().getText(); 返回的resultStr如果是"1"的话就说明MyQueue这个队列只有一个消费者。 然后,就没然后了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |