• java实现REST方式的webService


    此文章是基于  搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台

    一. 简介 

        WebService有两种方式,一是SOAP方式,二是REST方式。SOAP是基于XML的交互,WSDL也是一个XML文档,可以使用WSDL作为SOAP的描述文件;REST是基于HTTP协议的交互,支持JSON、XML等交互,不需要WSDL。
    

    二. jar包介绍

      1. 点击此下载 apache-cxf-3.0.3,并在 lib 文件夹下得到:

    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.jar

    三. 相关程序代码

      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工程配置文件

    <?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. 基础服务

        a. BaseService.java:接口

    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.jarMETA-INFcxfcxf.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
  • 相关阅读:
    Java 常见异常种类
    关系型数据库和非关系型数据库的区别
    HTTP中Get与Post的区别
    经典排序算法详细总结。
    新浪实时股票数据接口http://hq.sinajs.cn/list=股票代码
    WinIo驱动级键盘模拟编程
    Logback_日志使用详解(转)
    Java_位运算(移位、位与、或、异或、非)
    算法_bitmap算法
    Selenium_IEDriver操作sendkeys输入速度太慢
  • 原文地址:https://www.cnblogs.com/Mr-kevin/p/5806928.html
Copyright © 2020-2023  润新知