CXF--整合Spring

BtWangZhi發表於2017-10-28

將CXF整合到Spring,通過攔截部分請求由CXF進行處理
這裡寫圖片描述
1 在一個SSM專案POM.xml新增如下依賴:

<!-- Servlet支援 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0-b07</version>
        </dependency>

        <!-- JSP支援 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>

        <!-- JSTL支援 -->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!-- cxf核心包 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.8</version>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.4</version>
        </dependency>

1.1 web.xml中請求路由,部分請求由CXF進行處理

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!-- 編碼過濾器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- SpringMVC-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 表示哪些請求交給Spring Web MVC處理 -->
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <!-- CXF -->
    <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>/rest/*</url-pattern>
    </servlet-mapping>

1.2 Spring-Mvc配置

<?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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        ">

    <!-- 採用註解的方式配置bean -->
    <context:annotation-config />
    <!-- 配置要掃描的包 -->
    <context:component-scan base-package="com.test.cxf.controller" />

    <mvc:annotation-driven
        content-negotiation-manager="contentNegotiationManager" />
    <bean id="contentNegotiationManager"
        class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorPathExtension" value="false" />
        <property name="favorParameter" value="false" />
        <property name="ignoreAcceptHeader" value="false" />
        <property name="mediaTypes">
            <value>
                atom=application/atom+xml
                html=text/html
                json=application/json
                *=*/*
            </value>
        </property>
    </bean>
</beans>

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:context="http://www.springframework.org/schema/context"
    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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd  
        ">

    <!-- 採用註解的方式配置bean -->
    <context:annotation-config />
    <!-- 配置要掃描的包 -->
    <context:component-scan base-package="com.test.cxf.service" />

    <!-- CXF配置 -->
    <import resource="spring-cxf.xml"/>
</beans>

CXF配置:

<?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:context="http://www.springframework.org/schema/context"
    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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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
        ">

    <bean id="LoggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
    <bean id="LoggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
    <bean id="CxfResponseInterceptor" class="com.test.cxf.interceptor.CxfResponseInterceptor" />

    <bean id="SimpleConverter" class="org.codehaus.jettison.mapped.SimpleConverter" />
    <bean id="JSONProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="typeConverter" ref="SimpleConverter" />
        <property name="arrayKeys" value="memberName" />
    </bean>

    <jaxrs:server id="serviceContainer" address="/">
        <jaxrs:serviceBeans>
            <!-- 注入暴露出去的介面的實現類 -->
            <ref bean="userServiceImpl" />
        </jaxrs:serviceBeans>
        <!-- 輸入日誌攔截器 -->
        <jaxrs:inInterceptors>
            <ref bean="LoggingInInterceptor" />
        </jaxrs:inInterceptors>
        <!-- 輸出攔截器 -->
        <jaxrs:outInterceptors>
            <!-- 輸出日誌攔截器 -->
            <ref bean="LoggingOutInterceptor" />
            <!-- 輸出響應攔截器 -->
            <ref bean="CxfResponseInterceptor" />
        </jaxrs:outInterceptors>
        <jaxrs:providers>
            <ref bean="JSONProvider" />
        </jaxrs:providers>
        <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>

2 程式碼
2.1 SpringMVC請求Demo

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @ResponseBody
    @RequestMapping(value="/getUserInfo/{userId}",method=RequestMethod.GET)
    public Object getUserInfo(@PathVariable("userId")Integer userId) {
        System.out.println("run in UserController-->getUserInfo");
        return userService.getUserInfoByPathParam(userId);
    }
}

CXF攔截器:

/**
 * Cxf響應攔截器
 */
public class CxfResponseInterceptor extends AbstractPhaseInterceptor<Message>{

    public CxfResponseInterceptor() {
        super(Phase.PRE_STREAM);
    }

    public void handleMessage(Message message) throws Fault {
        //獲取所有的header
        Map<String, List<String>> headers = Headers.getSetProtocolHeaders(message);
        try {
            // 指定允許其他域名訪問
            headers.put("Access-Control-Allow-Origin", Arrays.asList("*"));
            // 響應型別
            headers.put("Access-Control-Allow-Methods", Arrays.asList("POST", "GET", "OPTIONS"));
            // 響應頭設定
            headers.put("Access-Control-Allow-Headers", Arrays.asList("Content-Type", "Accept", "X-Requested-With", "Authorization"));
        } catch (Exception ce) {
            throw new Fault(ce);
        }
    }
}

CXF請求處理中心

@Produces({"application/json;charset=UTF-8", "application/xml;charset=UTF-8",
    "text/javascript;charset=UTF-8", "text/plain;charset=utf-8"})
public interface UserService {

    /**
     * 測試PathParam註解
     * @param userId
     * @return
     */
    @GET
    @Path("/user/getUserInfoByPathParam/{userId}")
    public User getUserInfoByPathParam(@PathParam("userId")Integer userId);

    /**
     * 測試QueryParam註解
     * @param userId
     * @return
     */
    @GET
    @Path("/user/getUserInfoByQuery")
    public User getUserInfoByQuery(@QueryParam("userId")Integer userId);
}

實現類:

@Service
public class UserServiceImpl implements UserService{

    public User getUserInfoByPathParam(Integer userId) {
        User user=new User();
        user.setId(userId);
        user.setName("張三");
        user.setPassword("123");
        return user;
    }

    public User getUserInfoByQuery(Integer userId) {
        User user=new User();
        user.setId(userId);
        user.setName("張三");
        user.setPassword("456");
        return user;
    }

pojo:

@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User  implements Serializable {

    private static final long serialVersionUID = 1L;

    @XmlElement(name="id")
    private Integer id;

    @XmlElement(name="name")
    private String name;

    @XmlElement(name="password")
    private String password;
    //省略get/set
}

測試:

public static void main(String[] args) {
        //測試PathParam註解
        String resultData = doGet("http://localhost:8080/CXF01/rest/user/getUserInfoByPathParam/1", null);
        System.out.println(resultData);

        //測試QueryParam註解
        Map<String,String> data=new HashMap<>();
        data.put("userId", "1");
        String resultData=doGet("http://localhost:8080/CXF01/rest/user/getUserInfoByQuery", data);
        System.out.println(resultData);

相關文章