1. 程式人生 > >遠端呼叫 HttpInvoker JSP工程之間的資料互動

遠端呼叫 HttpInvoker JSP工程之間的資料互動

在這裡我所實現的一個功能是點選一個按鈕需要將PCS工程的資料傳遞到PIS然後交由其對資料進行更新操作。

1、PIS上的相關配置與檔案   (伺服器端)

web.xml  裡新增下述相關內容

 <!--與PCS工程互動的配置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/META-INF/**/spring-*.xml,classpath*:/META-INF/**/remote-servlet.xml</param-value>
    </context-param>
    <!-- spring 載入監視器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.yihaodian.pis.webapp.listener.AppRequestListener</listener-class>
    </listener>
 <servlet>
	<servlet-name>remote</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>remote</servlet-name>
	<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
<!-- 另一個工程的配置-->
 <servlet>
        <description>HTTP Exporters</description>
        <servlet-name>services</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>services</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

 remote-servlet.xml  的內容           將PIS的BEAN暴露給PCS然PCS對其進行呼叫

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
   <bean id="rmiService" class="com.yihaodian.pis.service.testremoteinvoke.IRemoteServiceImpl"></bean>
    <bean class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter" name="/remoteService">
        <property name="service" ref="rmiService" />
        <property name="serviceInterface" value="com.yihaodian.pis.service.testremoteinvoke.IRemoteService"/>
    </bean>
</beans>
 

介面以及其實現類(有PCS對其實現類的方法進行呼叫)

實現類IRemoteServiceImpl。java:

package com.yihaodian.pis.service.testremoteinvoke;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.newheight.service.webservice.dto.BackOperator;
import com.yihaodian.pis.dto.ProductHistoryDTO;
import com.yihaodian.pis.dto.TaskDto;
import com.yihaodian.pis.service.TaskService;

public class IRemoteServiceImpl implements IRemoteService {
	private static final Logger logger = Logger
			.getLogger(IRemoteServiceImpl.class);

	public String getString(String msg) {
		String str = "正在請求呼叫。。。遠端服務呼叫成功" + msg;
		return str;
	}

	public String getProduct(String siteid, String productCode) {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "classpath*:/META-INF/**/spring-*.xml" });
		TaskService taskSvc = (TaskService) context.getBean("taskSvc");
		//當資料很多時就會出現陣列指數出界
		String[] site = siteid.split(",");
		String[] productCodes = productCode.split(",");
		int len = site.length;
		Integer[] taskIds = new Integer[len];
		for (int i = 0; i < len; i++) {
			TaskDto taskDto = new TaskDto();
			String codes = productCodes[i];
			if (null != codes && !"".equals(codes)) {
				codes = StringUtils.replace(codes, "\r\n",
						System.getProperty("line.separator"));
				taskDto.setProductCodes(codes);
			}
			taskDto.setRunStatus(TaskDto.RunStatus.BEGIN.ordinal());
			taskDto.setProcessStatus(TaskDto.ProcessStatus.WAIT.ordinal());
			// 獲取已登入使用者的資訊
			// Long userId = ((BackOperator) ServletActionContext.getRequest()
			// .getSession().getAttribute("admin")).getId();
			Long userId = (long) 6660;
			taskDto.setUserId(userId);
			taskDto.setStartTime(new Date());
			taskDto.setName("PCS比價執行第" + (i + 1) + "任務");
			taskDto.setDescription("PCS抓價任務");
			taskDto.setType(2);
			taskDto.setSiteId(Integer.parseInt(site[i]));
			taskDto.setTaskId(taskSvc.addTask(taskDto));
			taskIds[i] = taskDto.getTaskId();

			try {
				taskSvc.batchFetchProductPrice(taskDto.getTaskId());
			} catch (Exception e) {
				logger.error("批量抓價出錯:", e);
			}
		}
		// 在此處檢查任務的完成情況。
		int allTime =0;
		int doneTask = 0;
		for (int i = 0; i < len; i++) {
			boolean index = true;
			while (index) {
				TaskDto task = taskSvc.getTaskById(taskIds[i]);
				if (task.getRunStatus() == 4) {
					logger.info("任務" + taskIds[i] + "已經完成!");
					taskSvc.persistPriceJob(taskIds[i]);
					doneTask++;
					index = false;
				} else {
					if(allTime<60){//超時
					allTime =allTime + 5;
					sleep(10000);//睡眠一段時間後繼續檢檢視是否完成任務
					}else break;
				}
			}
		}
		if(doneTask<len)
			return "未能正常完成更新,可能有以下幾個原因,1、當前任務太多,出現任務超時,2、PIS爬蟲不夠,3、系統異常";
		else
			return "恭喜,圓滿完成任務!";
	}

	public void sleep(long ms) {
		try {
			Thread.sleep(ms);
		} catch (InterruptedException ex) {
			ex.printStackTrace(System.out);
		}
	}

	public static Logger getLogger() {
		return logger;
	}
}

 2、PCS工程的相關檔案與配置

介面類IRemoteService。java

package com.yihaodian.pis.service.testremoteinvoke;

import java.util.List;

import com.yihaodian.pcs.dto.ProductHistoryDTO;

public interface IRemoteService {
	public String getString(String msg);
	public String getProduct(String siteid,String productCode);
}
 

在SPING裡新建一個用來呼叫方法的BEAN 

<!-- 向旗新增PCS與PIS資料互動     -->
<bean id="remoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
        <property name="serviceUrl" value="http://127.0.0.1:8080/pis1.2/remoting/remoteService"/> 
        <property name="serviceInterface" value="com.yihaodian.pis.service.testremoteinvoke.IRemoteService"/> 
    </bean> 

 以上VALUE屬性與PIS的IP和WEB.XML裡的配置有關,另外如果一臺電腦無法執行兩個工程,可以更改伺服器的埠號。

在這裡我將PCS的埠號改為8880,直接能夠在TOMCAT上執行。

然後再ACTION得到上述的BEAN物件對介面對映到PIS的方法進行呼叫

ApplicationContext beanAccontext = WebApplicationContextUtils
		.getRequiredWebApplicationContext(ServletActionContext
				.getServletContext());
		IRemoteService reService = (IRemoteService) beanAccontext.getBean("remoteService");
		//以下為返回的結果。
		String mString= "";
		try {
			mString= reService.getProduct(siteAll,proCodeAll);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info(mString);

不懂的聯絡QQ526151410