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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM