Spring集成hessian遇到的大坑

今天在使用Spring+hessian访问远程服务的时候,遇到两个问题,使用 Spring版本是4.3.6.RELEASE。

首先在Spring-servlet.xml里配置的hessian的bean:

<!-- hessian的bean开始 -->
<bean id="remotePortalService"
   class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
   <property name="serviceUrl">
      <value>${portalUrl}</value>
   </property>
   <property name="serviceInterface" value="com.suning.skyeye.intf.remote.PortalService"></property>
   <property name="overloadEnabled" value="true"></property>
</bean>

根据环境(sit\pre\prd)配置在配置文件中配置
portalUrl=http://xxx/xxx-web/RemoteApi/remotePortalService
在xml中使用:<context:property-placeholder location="classpath:conf/main-setting-$[envName].properties"/>来加载properties文件。
对应的bean实现:
@Controller
@RequestMapping("/romote")
public class PermissionControllor extends BaseCTBPMController {
    @Autowired
    private PortalService remotePortalService;
    @Autowired
    private ProductsConverter productsConverter;

    /**
     * 根据用户编号查询该用户能访问的产品
     *
     * @param request
     */
    @RequestMapping("/api/product.do")
    @Action(type = ViewType.API, name = "getUserProducts")
    public Object getUserProducts(HttpServletRequest request, HttpServletResponse response) {
        UserEntity user = getUserEntity(request);
        List<ProductDTO> productDTOS = new ArrayList<>();
        if (user == null) {
            List<ProductEo> userProducts = remotePortalService.getProducts("6f80bbbfc7d6442e80b9553f0a024b43");
            productDTOS = productsConverter.convertToDTOs(userProducts);
        }
        return productDTOS;
    }
}
遇到的问题:
1、当使用hessian的依赖为:
<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>3.1.5</version>
</dependency>
的时候,会报错:java.lang.ClassNotFoundException: com.caucho.hessian.client.HessianConnectionFactory,报错很明显是版本低了
2、当使用hessian的依赖为:
<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.7</version>
</dependency>
的时候,会报错:com.caucho.hessian.io.HessianProtocolException: expected integer at 0x74,很明显版本问题,
然后折腾了半天都没有找到合适的处理方法,但是知道的是使用Spring-3.1.2.RELEASE+3.1.5的hessian是没有问题的。实在是找不到问题所在,然后就放弃了使用Spring集成的HessianProxyFactoryBean来访问远程服务。

改为使用hessian的HessianProxyFactory来处理:
直接上代码:
<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.37</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>mirror.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>0.1-3_1_5</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
在Spring-servlet.xml中:
<bean id="prop" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <array>
            <value>classpath:conf/main-setting-$[envName].properties</value>
        </array>
    </property>
</bean>
来加载配置文件。
读取配置文件:
import lombok.Data;
import org.apache.commons.fileupload.FileUpload;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("fileUpload")
@Data
public class RemoteServiceProperties extends FileUpload {

    private String portalUrl;

    @Value("#{prop.portalUrl}")
    public void setPortalUrl(String portalUrl) {
        this.portalUrl = portalUrl;
    }
}
注解形式来连接远程:
import com.suning.skyeye.intf.remote.PortalService;
import lombok.extern.slf4j.Slf4j;
import mirror.caucho.hessian.client.HessianProxyFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.MalformedURLException;

/**
 * @author
 */
@Configuration
@Slf4j
public class RemoteServiceConfiguration {
    @Autowired
    private RemoteServiceProperties remoteServiceProperties;

    @Bean("remotePortalService")
    public PortalService remotePortalService() throws MalformedURLException {
        HessianProxyFactory proxyFactory = new HessianProxyFactory();
        return (PortalService) proxyFactory.create(PortalService.class, remoteServiceProperties.getPortalUrl());
    }
}
调用类:
import com.suning.ctbpm.dto.user.ProductDTO;
import com.suning.ctbpm.entity.UserEntity;
import com.suning.ctbpm.web.controller.base.BaseCTBPMController;
import com.suning.ctbpm.web.converter.ProductsConverter;
import com.suning.framework.ViewType;
import com.suning.framework.annotation.Action;
import com.suning.skyeye.intf.entity.ProductEo;
import com.suning.skyeye.intf.remote.PortalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/romote")
public class PermissionControllor extends BaseCTBPMController {
    @Autowired
    private PortalService remotePortalService;
    @Autowired
    private ProductsConverter productsConverter;

    /**
     * 根据用户编号查询该用户能访问的产品
     *
     * @param request
     */
    @RequestMapping("/api/product.do")
    @Action(type = ViewType.API, name = "getUserProducts")
    public Object getUserProducts(HttpServletRequest request, HttpServletResponse response) {
        UserEntity user = getUserEntity(request);
        List<ProductDTO> productDTOS = new ArrayList<>();
        if (user == null) {
            List<ProductEo> userProducts = remotePortalService.getProducts("6f80bbbfc7d6442e80b9553f0a024b43");
            productDTOS = productsConverter.convertToDTOs(userProducts);
        }
        return productDTOS;
    }
import com.suning.ctbpm.dto.user.ProductDTO;
import com.suning.ctbpm.util.BaseConverter;
import com.suning.skyeye.intf.entity.ProductEo;
import org.springframework.stereotype.Component;
@Component
public class ProductsConverter extends BaseConverter<ProductDTO, ProductEo> {
    @Override
    protected ProductEo doForward(ProductDTO productDTO) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    protected ProductDTO doBackward(ProductEo productEo) {
        return new ProductDTO().setAppCode(productEo.getProductCode()).setAppName(productEo.getDescription());
    }
}

}

就可以正常访问远程接口了。
这里主要要理解hessian和Spring加载配置文件。

作者:敲完代码好睡觉

本文版权归作者所有,欢迎转载,请在文章页面明显位置给出原文连接:https://www.cnblogs.com/wynjauu/articles/9360570.html

posted @ 2018-06-20 16:30  舞羊  阅读(5280)  评论(1编辑  收藏  举报