java實現REST方式的webService

此文章是基於  搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平臺html

 

一. 簡介 java

    WebService有兩種方式,一是SOAP方式,二是REST方式。SOAP是基於XML的交互,WSDL也是一個XML文檔,能夠使用WSDL做爲SOAP的描述文件;REST是基於HTTP協議的交互,支持JSON、XML等交互,不須要WSDL。

 

二. jar包介紹web

  1. 點擊此下載 apache-cxf-3.0.3,並在 lib 文件夾下獲得:spring

commons-codec-1.9.jar
cxf-core-3.0.3.jar
cxf-rt-frontend-jaxrs-3.0.3.jar
cxf-rt-transports-http-3.0.3.jar
javax.ws.rs-api-2.0.1.jar
View Code

  2. commons-httpclient-3.1.jarapache

 

三. 相關程序代碼api

  1. applicationInterface.xml:spring配置文件多線程

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
        
    <!-- cxf發佈rest服務 -->
    <import resource="classpath:META-INF/cxf/cxf.xml"/>   
    <!-- 這裏是cxf2.x版本的配置,3.0沒有了要去掉 --> 
    <!-- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> -->
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
    <bean id="receiver" class="com.ims.test.webService.cxf.Receiver" />

    <jaxrs:server id="serviceContainer" address="/">    
        <jaxrs:serviceBeans>        
            <ref bean="receiver" />    
        </jaxrs:serviceBeans>    
    </jaxrs:server>
    <!-- cxf發佈rest服務 -->
    
</beans>
View Code

  2. web.xml:web工程配置文件app

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd 
        http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    version="2.4">

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            classpath:applicationInterface.xml
    </param-value>
  </context-param>
              
  <servlet>
      <servlet-name>CXFServlet</servlet-name>
      <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  </servlet>
    
  <servlet-mapping>
      <servlet-name>CXFServlet</servlet-name>
      <url-pattern>/service/*</url-pattern>
  </servlet-mapping>

</web-app>
View Code

  3. 基礎服務frontend

    a. BaseService.java:接口eclipse

package com.ims.interfaces.webService.cxf;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

public interface BaseService {
    @POST   
    @Consumes(MediaType.TEXT_HTML)
    @Produces(MediaType.TEXT_HTML)
    public void execute(@QueryParam("type") String type);
}
View Code

    b. BaseServiceImpl.java:實現

package com.ims.interfaces.webService.cxf;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

/**
 * 基礎服務接口
 */
public abstract class BaseServiceImpl implements BaseService{
    @Context    
    protected HttpServletRequest request;
    @Context 
    protected HttpServletResponse response;
    
    @Override
    @POST
    @Consumes(MediaType.TEXT_HTML)
    @Produces(MediaType.TEXT_HTML) 
    public void execute(@QueryParam("type") String type) {        
        try {        
            // 獲取請求類型
            RequestType reqType = RequestType.getTypeByCode(Integer.valueOf(type));
            
            // 獲取HTTP請求體XML字符輸入流
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(
                    new BufferedInputStream(request.getInputStream()), "gb2312"));
            
            // 業務處理
            ResponseResult result = process(reqType, reader);
            // 設置響應編碼
            response.setStatus(result.getStatus().getCode());
            
            // 輸出響應體
            response.setCharacterEncoding("gb2312");
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(result.getResult().getBytes("gb2312"));
        }
        catch (IOException ioe) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    public abstract ResponseResult process(RequestType reqType, BufferedReader reader);
}
View Code

  4. Receiver.java:接收端類

package com.ims.test.webService.cxf;

import java.io.BufferedReader;

import javax.ws.rs.Path;

import com.ims.interfaces.webService.cxf.BaseServiceImpl;
import com.ims.interfaces.webService.cxf.RequestType;
import com.ims.interfaces.webService.cxf.ResponseResult;
import com.ims.interfaces.webService.cxf.ResponseStatus;


@Path(value = "/receive.do")
public class Receiver extends BaseServiceImpl {

    @Override
    public ResponseResult process(RequestType reqType, BufferedReader reader) {
        ResponseResult result = null;
        
        switch(reqType){
            case UNKNOWN:
                result = new ResponseResult(ResponseStatus.CODE400, "");
                break;
            default:
                break;
        }
        
        return result;
    }

}
View Code

  5. Sender.java:發送端類

package com.ims.test.webService.cxf;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

public class Sender {
    
    public static void main(String[] args) {
        String url = "http://localhost:8090/ims/service/receive.do?type=0";
        String xmlString = "<?xml version=\"1.0\" encoding=\"gbk\"?>";
        post(url, xmlString); 
    }
    
    /**
     * 發送xml數據請求到server端
     * @param url xml請求數據地址
     * @param xmlString 發送的xml數據流
     * @return null發送失敗,不然返回響應內容  
     */
    public static boolean post(String url,String xmlString){  
        boolean result = false;
        //建立httpclient工具對象   
        HttpClient client = new HttpClient();    
        //建立post請求方法   
        PostMethod myPost = new PostMethod(url);    
        //設置請求超時時間
        client.getHttpConnectionManager().getParams().setConnectionTimeout(300*1000); 

        try{    
            //設置請求頭部類型   
            myPost.setRequestHeader("Content-Type","text/html");  
            myPost.setRequestEntity(new StringRequestEntity(xmlString,"text/html","gbk"));     
            int statusCode = client.executeMethod(myPost);    
            if(statusCode == HttpStatus.SC_OK){
                result = true;  
            }              
        }catch (Exception e) {    
            e.printStackTrace();    
        }finally{
            myPost.releaseConnection(); 
        }          
        return result;    
    }
}
View Code


四. 測試

  eclipse上啓動ims工程(webService接收端),以java執行Sender類,eclipse上調試查看Receive類是否收到xml文件

 

五. 備註

  1. cxf 是支持多線程的,默認的線程池配置可查看 org.apache.cxf.workqueue.AutomaticWorkQueueImpl 源文件:

static final int DEFAULT_MAX_QUEUE_SIZE = 256;
    
。。。。。。。。。

public AutomaticWorkQueueImpl() {
        this(DEFAULT_MAX_QUEUE_SIZE);
    }    
    public AutomaticWorkQueueImpl(String name) {
        this(DEFAULT_MAX_QUEUE_SIZE, name);
    }    
    public AutomaticWorkQueueImpl(int max) {
        this(max, "default");
    }
    public AutomaticWorkQueueImpl(int max, String name) {
        this(max,
             0,
             25,
             5,
             2 * 60 * 1000L,
             name);
    }
    public AutomaticWorkQueueImpl(int mqs, 
                                  int initialThreads, 
                                  int highWaterMark, 
                                  int lowWaterMark,
                                  long dequeueTimeout) {
        this(mqs, initialThreads, highWaterMark, lowWaterMark, dequeueTimeout, "default");
    }    
    public AutomaticWorkQueueImpl(int mqs, 
                                  int initialThreads, 
                                  int highWaterMark, 
                                  int lowWaterMark,
                                  long dequeueTimeout,
                                  String name) {
        this.maxQueueSize = mqs == -1 ? DEFAULT_MAX_QUEUE_SIZE : mqs;
        this.initialThreads = initialThreads;
        this.highWaterMark = -1 == highWaterMark ? Integer.MAX_VALUE : highWaterMark;
        this.lowWaterMark = -1 == lowWaterMark ? Integer.MAX_VALUE : lowWaterMark;
        this.dequeueTimeout = dequeueTimeout;
        this.name = name;
        this.changeListenerList = new ArrayList<PropertyChangeListener>();
    }

。。。。。。。。。

protected synchronized ThreadPoolExecutor getExecutor() {
        if (executor == null) {
            threadFactory = createThreadFactory(name);
            executor = new ThreadPoolExecutor(lowWaterMark, 
                                              highWaterMark,
                                              TimeUnit.MILLISECONDS.toMillis(dequeueTimeout), 
                                              TimeUnit.MILLISECONDS, 
                                              new LinkedBlockingQueue<Runnable>(maxQueueSize),
                                              threadFactory) {
                @Override
                protected void terminated() {
                    ThreadFactory f = executor.getThreadFactory();
                    if (f instanceof AWQThreadFactory) {
                        ((AWQThreadFactory)f).shutdown();
                    }
                    if (watchDog != null) {
                        watchDog.shutdown();
                    }
                }
            };
View Code

  2. 若要配置線程池參數,可配置 cxf-core-3.0.3.jar\META-INF\cxf\cxf.xml 文件:

<bean id="default-wq" class="org.apache.cxf.workqueue.AutomaticWorkQueueImpl">
    <constructor-arg index="0">
        <!-- Max number of elements in the queue -->
        <value>20000</value>
    </constructor-arg>
    <constructor-arg index="1">
        <!-- name -->
        <value>default</value>
    </constructor-arg>
    <property name="name" value="default" />
    <property name="highWaterMark" value="30" />
</bean>
View Code
相關文章
相關標籤/搜索