走向REST:将Tomcat与Spring和JAX-RS嵌入(Apache CXF)

这篇文章是上一篇文章的逻辑延续。 唯一的区别是我们将使用的容器:它将是我们的老兄Apache Tomcat而不是Jetty 。 令人惊讶的是,嵌入最新的Apache Tomcat 7非常容易,因此现在让我展示一下。 我不会重复完整的上一篇文章 ,因为除了POM文件Starter类之外没有任何更改。 除了这两个之外,我们正在重用以前所做的一切。 对于POM文件,我们需要删除Jetty依赖性并将其替换为Apache Tomcat 。 第一个更改将在properties部分中,我们将用org.apache.tomcat替换org.eclipse.jetty.version

所以这行:

<org.eclipse.jetty.version>8.1.8.v20121106</org.eclipse.jetty.version>

变成:

<org.apache.tomcat>7.0.34</org.apache.tomcat>

第二个更改是依赖关系本身,我们将替换以下行:

<dependency>
    <groupid>org.eclipse.jetty</groupid>
    <artifactid>jetty-server</artifactid>
    <version>${org.eclipse.jetty.version}</version>
</dependency>
     
<dependency>
    <groupid>org.eclipse.jetty</groupid>
    <artifactid>jetty-webapp</artifactid>
    <version>${org.eclipse.jetty.version</version>
</dependency>

这些:

<dependency>
    <groupid>org.apache.tomcat.embed</groupid>
    <artifactid>tomcat-embed-core</artifactid>
    <version>${org.apache.tomcat}</version>
</dependency>
  
<dependency>
    <groupid>org.apache.tomcat.embed</groupid>
    <artifactid>tomcat-embed-logging-juli</artifactid>
    <version>${org.apache.tomcat}</version>
</dependency>

太好了,这部分完成了。 最后一部分专门讨论主类实现中的更改,我们将用Apache Tomcat替换Jetty

package com.example;

import java.io.File;
import java.io.IOException;

import org.apache.catalina.Context;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import com.example.config.AppConfig;

public class Starter { 
    private final static Log log = LogFactory.getLog( Starter.class );
 
    public static void main(final String[] args) throws Exception {
        final File base = createBaseDirectory();
        log.info( "Using base folder: " + base.getAbsolutePath() );
  
        final Tomcat tomcat = new Tomcat();
        tomcat.setPort( 8080 );
        tomcat.setBaseDir( base.getAbsolutePath() ); 
  
        Context context = tomcat.addContext( "/", base.getAbsolutePath() );
        Tomcat.addServlet( context, "CXFServlet", new CXFServlet() );
  
        context.addServletMapping( "/rest/*", "CXFServlet" );
        context.addApplicationListener( ContextLoaderListener.class.getName() );
        context.setLoader( new WebappLoader( Thread.currentThread().getContextClassLoader() ) );
  
        context.addParameter( "contextClass", AnnotationConfigWebApplicationContext.class.getName() );
        context.addParameter( "contextConfigLocation", AppConfig.class.getName() );
   
        tomcat.start();
        tomcat.getServer().await();
    }

    private static File createBaseDirectory() throws IOException {
        final File base = File.createTempFile( "tmp-", "" );
  
        if( !base.delete() ) {
            throw new IOException( "Cannot (re)create base folder: " + base.getAbsolutePath()  );
        }
  
        if( !base.mkdir() ) {
            throw new IOException( "Cannot create base folder: " + base.getAbsolutePath()  );         
        }
  
        return base;
    } 
}

该代码看起来非常简单但冗长,因为在没有指定某些工作目录的情况下似乎不可能以嵌入式模式运行Apache Tomcat 。 小小的createBaseDirectory()函数创建一个临时文件夹,我们将其作为baseDir馈入Apache Tomcat 。 实现表明,我们正在端口8080上运行Apache Tomcat服务器实例,我们正在配置Apache CXF servlet来处理/ rest / *路径上的所有请求,我们将添加Spring上下文侦听器,最后将服务器启动。

将项目构建为一个胖子或一个罐子之后 ,我们将拥有一个功能完善的服务器来托管我们的JAR-RS应用程序:

mvn clean package
java -jar target/spring-one-jar-0.0.1-SNAPSHOT.one-jar.jar

我们应该看到这样的输出:

Jan 28, 2013 5:54:56 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ['http-bio-8080']
Jan 28, 2013 5:54:56 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Jan 28, 2013 5:54:56 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.34
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/jsp_2_0.xsd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/jsp_2_1.xsd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/jsp_2_2.xsd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd
Jan 28, 2013 5:54:56 PM org.apache.catalina.startup.DigesterFactory register
WARNING: Could not get url for /javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd
Jan 28, 2013 5:54:57 PM org.apache.catalina.loader.WebappLoader setClassPath
INFO: Unknown loader com.simontuffs.onejar.JarClassLoader@187a84e4 class com.simontuffs.onejar.JarClassLoader
Jan 28, 2013 5:54:57 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Jan 28, 2013 5:54:57 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
Jan 28, 2013 5:54:58 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing Root WebApplicationContext: startup date [Mon Jan 28 17:54:58 EST 2013]; root of context hierarchy
Jan 28, 2013 5:54:58 PM org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider registerDefaultFilters
INFO: JSR-330 'javax.inject.Named' annotation found and supported for component scanning
Jan 28, 2013 5:54:58 PM org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
INFO: Successfully resolved class for [com.example.config.AppConfig]
Jan 28, 2013 5:54:58 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 

INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Jan 28, 2013 5:54:58 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@62770d2e: defining beans [org.springframework.context.annotation.internal
ConfigurationAnnotationProcessor,org.springframework.context.annotation.
internalAutowiredAnnotationProcessor,org.springframework.context.annotation.
internalRequiredAnnotationProces
sor,org.springframework.context.annotation.internalCommonAnnotationProcessor,
appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.
importAwareProcessor,
cxf,jaxRsServer,jaxRsApiApplication,peopleRestService,peopleService,jsonProvider]; root of factory hierarchy
Jan 28, 2013 5:54:59 PM org.apache.cxf.endpoint.ServerImpl initDestination
INFO: Setting the server's publish address to be /api
Jan 28, 2013 5:54:59 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 1747 ms
Jan 28, 2013 5:54:59 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ['http-bio-8080']

让我们发出一些HTTP请求,以确保一切正常。

> curl http://localhost:8080/rest/api/people?page=2
[
  {'email':'person+6@at.com','firstName':null,'lastName':null},
  {'email':'person+7@at.com','firstName':null,'lastName':null},
  {'email':'person+8@at.com','firstName':null,'lastName':null}, 
  {'email':'person+9@at.com','firstName':null,'lastName':null}, 
  {'email':'person+10@at.com','firstName':null,'lastName':null}
]

> curl http://localhost:8080/rest/api/people -X PUT -d 'email=a@b.com'
{'email':'a@b.com','firstName':null,'lastName':null}

而且我们仍然100%免费提供XML ! 不过,有一个重要的注意事项 :我们每次都会创建一个临时文件夹,但永远不会删除它(对base调用deleteOnShutdown不能像预期的那样对非空文件夹起作用)。 当我决定保持代码整洁时,请记住这一点(例如,添加您自己的关闭挂钩)。

参考: http //aredko.blogspot.gr/2013/01/going-rest-embedding-tomcat-with-spring.html(来自Andriy Redko {devmind}博客上的JCG合作伙伴 Andrey Redko)。

翻译自: https://www.javacodegeeks.com/2013/02/going-rest-embedding-tomcat-with-spring-and-jax-rs-apache-cxf.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值