Apache cxf JaxRs基本应用

在前一篇中,我们完成了《Apache cxf JaxWs基本应用》 的编写,我们现在实现一个Restful风格的Cxf 。

一、我们首先依旧是基于Maven project配置pom.xml的依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<artifactId>abc-api</artifactId>
	<packaging>war</packaging>
	<version>${global.version}</version>
	
	<parent>
		<groupId>com.abc.module</groupId>
		<artifactId>abc-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	
	<dependencies>
		<dependency>
			<groupId>javax.ws.rs</groupId>
			<artifactId>jsr311-api</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>2.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>2.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
			<version>2.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jettison</groupId>
			<artifactId>jettison</artifactId>
			<version>1.3.5</version>
		</dependency>
		<dependency>
			<groupId>axis</groupId>
			<artifactId>axis</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.woodstox</groupId>
			<artifactId>stax2-api</artifactId>
			<version>3.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.jbarcode</groupId>
			<artifactId>jbarcode</artifactId>
			<version>0.2.8</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

二、配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>fsp-api</display-name>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:application.xml</param-value>
	</context-param>

	<!-- spring context listener -->
	<listener>
		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- CXF -->
	<servlet>
		<servlet-name>cxf</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>cxf</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>
	
</web-app>

三、创建Webservice对外接口

/**
 * Copyright (c) 2011-2014 All Rights Reserved.
 */
package com.abc.warehouse.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

@Path("/logisticsApi")
public interface ILogisticsApi {

    @GET
    @Path("/doGet/{first}/{last}")
    @Produces(MediaType.APPLICATION_XML)
    public String doGet(@PathParam(value = "first") String firstName, @PathParam(value = "last") String lastName);
    
    
    @POST
    @Path("/itemConfirm")
    @Produces(MediaType.APPLICATION_XML)
    public String itemConfirm(String xmlParam,
                                    @Context HttpServletRequest servletRequest, 
                                    @Context HttpServletResponse servletResponse);

}

四、实现Webservice接口

/**
 * Copyright (c) 2011-2014 All Rights Reserved.
 */
package com.abc.api.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.abc.warehouse.service.ILogisticsApi;


public class LogisticsApiImpl implements ILogisticsApi {

    private Logger log = LoggerFactory.getLogger(getClass());
    
    /** 
     * @see com.abc.warehouse.service.ILogisticsApi#itemConfirm(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public String itemConfirm(String xmlParam,
                                    HttpServletRequest servletRequest, 
                                    HttpServletResponse servletResponse) {
        // TODO Auto-generated method stub
        // to do something ...

        return response;
    }


    /** 
     * @see com.abc.warehouse.service.ILogisticsApi#doGet(java.lang.String, java.lang.String)
     */
    @Override
    public String doGet(String firstName, String lastName) {
        // TODO Auto-generated method stub
        log.debug("doGet : " + firstName + ", lastName : " + lastName);
        // to to something ...

        return response;
    }



}

五、配置Spring xml,让Webservice提供服务

<?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:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
                    http://cxf.apache.org/jaxrs
					http://cxf.apache.org/schemas/jaxrs.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<bean id="encodingLoggingInInterceptor" class="com.abc.api.util.EncodingLoggingInInterceptor"/>
	<bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
	<bean id="logisticsApi" class="com.abc.api.service.LogisticsApiImpl"/>
	<jaxrs:server id="logisticsApiServiceContainer">
	    <jaxrs:serviceBeans>
	        <ref bean="logisticsApi" />
	    </jaxrs:serviceBeans>
	    
		<jaxrs:inInterceptors>
			<ref bean="encodingLoggingInInterceptor"/>
		</jaxrs:inInterceptors>
	    <jaxrs:outInterceptors>
	    	<ref bean="outLoggingInterceptor"/>
	    </jaxrs:outInterceptors>
		
	    <jaxrs:extensionMappings>
	        <!-- <entry key="json" value="application/json" /> -->
	        <entry key="xml" value="application/xml" />
	    </jaxrs:extensionMappings>
	
	    <jaxrs:languageMappings>
	        <entry key="en" value="en-gb"/>  
	    </jaxrs:languageMappings>
	</jaxrs:server>

</beans>

其中EncodingLoggingInInterceptor类主要是为了解决传输内容在LoggingInInterceptor类内构建并输出时的乱码问题

/**
 * Copyright (c) 2011-2014 All Rights Reserved.
 */
package com.abc.api.util;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class EncodingLoggingInInterceptor extends LoggingInInterceptor {

    private Logger log = LoggerFactory.getLogger(getClass());
    
    /**
     * 
     */
    public EncodingLoggingInInterceptor() {
        // TODO Auto-generated constructor stub
        super();
    }
    
    /** 
     * @see org.apache.cxf.interceptor.LoggingInInterceptor#handleMessage(org.apache.cxf.message.Message)
     */
    @Override
    public void handleMessage(Message message) throws Fault {
        // TODO Auto-generated method stub
        
        String encoding = System.getProperty("file.encoding");
        encoding = encoding == null || encoding.equals("") ? "UTF-8" : encoding;
        
        log.debug("encoding : " + encoding);
        message.put(Message.ENCODING, encoding);
        
        super.handleMessage(message);
    }
}

至此,Webservice服务器端代码已经编写完成,假设Maven project名字为abc-api,那么访问该Webservice接口的地址为:http://ip:port/abc-api/services/


六、接下来我们编写一个基于WebClient简单客户端

/**
 * Copyright (c) 2011-2014 All Rights Reserved.
 */
package com.abc.api.service;

import static org.junit.Assert.*;

import javax.ws.rs.core.MediaType;

import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class LogisticsApiTester {

    private WebClient client;
    private String baseAddress = "http://localhost:8080/abc-api/services/logisticsApi";
    /**
     * 
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        client = WebClient.create(baseAddress)
            .header("charset", "UTF-8")
            .encoding("UTF-8")
            .acceptEncoding("UTF-8");
    }

    /**
     * 
     * @throws java.lang.Exception
     */
    @After
    public void tearDown() throws Exception {
        client = null;
    }

    /**
     * Test method for {@link com.abc.api.service.LogisticsApiImpl#itemConfirm(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}.
     */
    @Test
    public void testItemConfirm() {
        //fail("Not yet implemented");
        
        Object xmlParam = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<itemName>诺基亚</itemName>";
        String responseMessage = client.path("itemConfirm")
                                        .accept(MediaType.APPLICATION_XML)
                                        .post(xmlParam, String.class);
        System.out.println("responseMessage : " + responseMessage);
        assertNotEquals(responseMessage, null);
    }

    /**
     * Test method for {@link com.abc.api.service.LogisticsApiImpl#doGet(java.lang.String, java.lang.String)}.
     */
    @Test
    public void testDoGet() {
        //fail("Not yet implemented");
        
        String responseString = client.path("doGet/{first}/{last}", 1, 2)
                                    .accept(MediaType.APPLICATION_XML)
                                    .get(String.class);
        assertNotEquals(responseString, null);
    }


}


到这里我们就完成了基于Apache cxf JaxRs的服务端和客户端的Demo编写。






你可能感兴趣的:(CXF,Restful)