zoukankan      html  css  js  c++  java
  • zipkin:HttpClient和struts

      因为要和老系统集成zipkin,意外的发现老系统使用的httpClient来发送信息。zipkin的官方demo可都是retstTemplate啊!有的搞头。

      

    在看Demo的时候意外的发现其实其实2.5是支持httpClient的,只有到了spring 3之后才是restTemplate;但是我移植到了struts工程之后发现@Autowired的httpClient返回的是NULL;
    原来因为在spring的配置文件中的扫描路径有问题。但是改了路径依然没好,这是怎么回事;后来才发现原来报错的是strturs,strtus在分析spring的配置的时候当然报错了。后来单独设置了spring的servlet,再来定义问题解决。
    1 <servlet>
    2   <servlet-name>action</servlet-name>
    3   <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    4   <init-param>
    5     <param-name>config</param-name>
    6     <param-value>/WEB-INF/spring-webmvc-servlet.xml,/WEB-INF/struts-config.xml</param-value>
    7   </init-param>
    8   <load-on-startup>1</load-on-startup>
    9 </servlet>
    这样其实在web容器中其实跑的两套servlet,一套是struts一套是spring,剩下的servlet-mapping的事情了,决定那个路径转向那个servlet;每个servlet代表的一套解决方案,比如spring提供的是容器和挑转方案;struts(是struts 1)提供的跳转方案。那么两套方案是否可以结合,我的目标是容器采用spring,跳转采用struts,结合的时候,发生了一些事情。
    org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/spring-webmvc-servlet.xml]; nested exception is java.lang.IllegalStateException: Context namespace element 'component-scan' and its parser class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher
    但是我的已经是jdk 8的啊。后来看到stackoverflow里面的解释,只能用版本是1.5~1.7;check代码里面只是判断1.5,1.6,1.7,其他版本都被认为是1.4。这是spring里面的一段神判断,其实想想也是有道理,人家写这段代码的时候其实只是到1.7,至于1.8会发生什么无从知晓。
     1 static {
     2   javaVersion = System.getProperty("java.version");
     3   // version String should look like "1.4.2_10"
     4   if (javaVersion.indexOf("1.7.") != -1) {
     5     majorJavaVersion = JAVA_17;
     6   }
     7   else if (javaVersion.indexOf("1.6.") != -1) {
     8     majorJavaVersion = JAVA_16;
     9   }
    10   else if (javaVersion.indexOf("1.5.") != -1) {
    11     majorJavaVersion = JAVA_15;
    12   }
    13   else {
    14     // else leave 1.4 as default (it's either 1.4 or unknown)
    15     majorJavaVersion = JAVA_14;
    16   }
    17 }
    改了环境变量的路径配置;但是eclipse依然是jdk6,于是关掉elcipse,重启一下,重新读入一下jdk的系统配置;为什么在运行tomcat就不行?因为tomcat环境走的系统的jdk;在elipse里面走的编译是1.6;估计如果是运行其实也是eclipse内部配置;但是tomcat的运行就不行,其实是在eclipse之外跑的。
    于是尝试用了eclipse早起的版本,但是本地有的一个Luna版本貌似不是企业版的,没有sServer插件,于是在eclipse里面选择Install New Software...,然后在查询框中输入:
    Web、Xml、Java EE and OSGi Enterprise Development
    然后根据感觉选择相应的组件即可。
    后来换了mars,发现没有Dynamic Web Facts,这次在查询框中输入Web就可以了,根据感觉选就可以了。
     
    为什么在struts的action里面就是注入不了呢?
    其实不可能成功,spring来管理对象的时候,对于controller类是通过spring的对象池来创建,注入对象,在·DispatcherServlet处理的时候是从object pool中取出之前已经创建好的那个controller供处理请求;但是现在是struts来管理web请求;它是用他的方式来创建Action(相当于spring的controller),当然即使采用spring的声明也不会获取该对象;
     
    但是我使用
    1 WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
    2 HttpClient httpClient = (HttpClient)wac.getBean("httpClient");
    竟然告诉我httpClient没定义!我修改一下log4j的日志级别看看到底咋回事?但是从日志来看应该没问题;
    不行,我觉得应该是当前是struts的上下文,即使能够获得ContextLoader,但是此时其实根本就没有WebApplicationContext;后来我改了一种方式:
    1 ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
    2 new String[] { "applicationContext.xml","spring-webmvc-servlet.xml" });
    3 BeanFactory factory = (BeanFactory) appContext;
    4 HttpClient httpClient = (HttpClient)factory.getBean("httpClient");
    5 //appContext.close();
    6  
    7 return httpClient;
    这是在一段单例的对象中获得httpClient;这里有一个注释掉的appContext.close(),因为单例,所以不需要关闭;如果关闭,那么里面AsyncReporter报错,说是已经关闭;所以appContext要保留。这样写终于搞定了,看到zipkin里面有了日志的显示。
    虽然讲是sprinig和struts是两套环境,但是其实spring的容器是可以和struts共享的;后来我做了一下测试,在这个工程中配置了spring的servlet-mapping,然后开放了一个类标注为@Controller;发现通过 ContextLoader.getCurrentWebApplicationContext()也是无法获取“httpClient”,但是对象池子这次我特意跟进去,意外的发现对象池里面是有对象的,但是仅限于applicationContext;我其实在web.config里面配置了两个配置文件:spring-webmvc-servlet.xml和applicationContext;但是不知道什么原因只是有application里面出现的对象;后来我把spring-webmvc-servlet.xml里面的bean统一移动到application.xml文件中,发现都有了!这个?难道是spring 2.5的bug吗?我的写法就是最上面那段。
    可能是写法有问题,但是不纠结了,而且如果是集中在applicationContext.xml里面定义,struts里面通过ContextLoader.getCurrentWebApplicationContext()也是可以访问到httpClient对象的。
     
    但是现在的问题是:感觉没有了portal端的cr和cs,这是怎么回事?
    (未解)
     
    这一天下来,基本调通;我有一点没想通,为什么获取spring对象费了一些周折,但是Filter过滤器非常成功,因为门户的servlet处理,brave成功抓取发送:

      下图是brave-hc-client的信息;因为是sr和sc的,是servlet的brave成功捕获。

      这是因为web.xml里面的配置内容是tomcat要处理的内容,和框架无关(init-param里面定义的细节内容除外),比如servlet,filter等这些都是被tomcat使用;所以filter其实是被tomcat执行,和spring无关,于是servlet可以被DelegateFilter成功处理;但是到applicationContext.xml之类文件的处理(在web.xml文件<servlet>节点的configLocation中定义的配置文件路径)就是各个框架的servlet有针对性的处理,形成了差异化。或者讲,web.xml里面定义的都是全局性的东西,还没有到分context(上下文)的阶段;到了后面针对bean的处理就是只能是针对具体框架了。

  • 相关阅读:
    【Flume】数据采集引擎Flume
    【Spark】源码分析之SparkContext
    【Spark】源码分析之spark-submit
    【Hadoop故障处理】高可用(HA)环境DataNode问题
    【Hadoop故障处理】全分布下,DataNode进程正常启动,但是网页上不显示,并且DataNode节点为空
    【Hadoop故障处理】在高可用(HA)配置下,8088端口无法访问,resourcemanager进程无法启动问题
    【Spark】算子
    【Java】集合遍历--List和Map的多种遍历方式
    【Java】集合概述Collection、Map
    【Java】abstract,final,static,private,protected,public的区别
  • 原文地址:https://www.cnblogs.com/xiashiwendao/p/8835369.html
Copyright © 2011-2022 走看看