11

我有一些用 Java 编写的实用程序方法,用于针对服务创建测试数据。我的几个有相同用例的同事认为,如果他们可以重用它会很酷,但他们分别用 Perl 和 Python 编写测试。所以我正在考虑建立一个 JSON REST 服务来公开这些方法。

我编写网络应用程序的经验有限。站起来和部署我的服务的最快方法是什么?

我正在考虑使用 eclipse/spring 来完成它并使用 ant 部署在 Jetty 容器上。但我想听听您对此的经验。此外,似乎某些 IDE/插件对某些技术的支持比其他技术更好。所以我想听听 IDE/Plugins + J2EE 技术堆栈 + 服务器(如果这很重要)对于我的用例来说是一个很好的组合,以及为什么。我想坚持开源软件。

4

9 回答 9

12

我相信使用 Maven 可以让你尽快上手。这是你如何做到的。

它使用JAX-RS(用于 RESTful Web 服务的 Java API,Java EE 6 的官方部分)的RESTEasy实现。

这是一个具有最小结构的 java war maven 项目。这些是文件:

-pom.xml
-src
 |
  --main
    |
     --java
       |
        --rest
          |
           --HelloResource.java
           --JaxRsActivator.java

我称之为simpleRest如下所示。所有档案完全如图所示:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>simpleRest</groupId>
    <artifactId>simpleRest</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>2.3.1.GA</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <!-- So maven doesn't require web.xml -->
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

HelloResource.java

package rest;

import java.util.Date;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/hello")
public class HelloResource {
    @GET
    @Produces("text/plain")
    public String helloResource() {
        return "Hello! It's "+new Date();
    }
}

JaxRsActivator.java:

package rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/rest")
public class JaxRsActivator extends Application {

}

这会生成一个simpleRest.war(通过mvn clean package)。您可以将其部署到新安装的JBoss AS 7.1.1.Final(只需将 war 文件放入 deploy 文件夹)或Tomcat

之后,URL 按预期可用:

http://127.0.0.1:8080/simpleRest/rest/hello

那有多快?

于 2013-05-22T23:47:06.330 回答
5

这是我能想到的最简单的方法,它只需要 Java、 Gradle和文本编辑器即可实现功能齐全的 REST API 。在干净的项目目录中创建两个文件,如下所示:

构建.gradle

buildscript {
    repositories { mavenCentral() }
    dependencies {
        classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.8'
    }
}
apply plugin: 'tomcat'

repositories { mavenCentral() }
dependencies {
    compile(
        'com.sun.jersey:jersey-core:1.17',
        'com.sun.jersey:jersey-server:1.17',
        'com.sun.jersey:jersey-servlet:1.17',
        'com.sun.jersey:jersey-json:1.17',
    )
    tomcat(
        'org.apache.tomcat:tomcat-catalina:7.0.40',
        'org.apache.tomcat:tomcat-coyote:7.0.40',
        'org.apache.tomcat:tomcat-jasper:7.0.40',
    )
}

src/main/java/org/example/TheApplication.java

package org.example;

import com.sun.jersey.api.core.ClassNamesResourceConfig;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlRootElement;

@Path("/")
@ApplicationPath("/")
public class TheApplication extends ClassNamesResourceConfig {
    public TheApplication() { super(TheApplication.class); }

    static Foo foo = new Foo();

    @GET @Produces("application/json")
    public Foo getFoo() {
        return foo;
    }

    @POST @Consumes("application/json")
    public Response setFoo(Foo foo) {
        TheApplication.foo = foo;
        return Response.ok().entity("Stored it!").build();
    }

    @XmlRootElement
    static class Foo {
        private String message = "Hello World";
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }
}

一旦这两个文件就位,gradle tomcatRunWar将启动您的 REST API,并http://localhost:8080/fastest-web-service/在浏览器中导航到将为您提供“Hello World”JSON 消息。如果您随后发布类似的 JSON,例如使用 curl 或Poster指定 Content-Type 为“application/json”的{"message": "something else"}相同 URL ,则该新对象将被存储并在连续的 GET 请求中返回。这只是一个非常简单的示例,但涵盖了 JSON API 的许多基础知识。

IDE:您可以使用任何常见的 Java IDE 轻松地进一步开发它。IntelliJ IDEAEclipse的社区版都是流行的免费 IDE。<opinion>IDEA 更胜一筹,终极版比普通 Java 开发人员的个人许可证成本高出 110%。</opinion>

技术栈JAX-RS是用 Java 编写 REST API 的领先方式。选择任何实现。此示例使用Jersey,参考实现。如果您只需要一个简单的 API 来公开已经编写的逻辑,那么 Spring 可能会大材小用。它带来的复杂性超出了您的需要。另一方面,如果你需要一个更灵活、更强大的框架,它对世界上几乎所有的东西都有更多的内置支持,那么 Spring 可能就是你的选择。

服务器:支持 Servlet 3.0 的JettyTomcat 。或多或少不可能有任何原因。

于 2013-05-23T03:02:33.080 回答
1

好吧,我将把与 GlassFish 3.x 捆绑在一起的 NetBeans IDE 扔进环中。

下载该包并安装它,然后只需右键单击向导即可提供服务的 JAX-RS。一次下载,一次安装,完全全面。大量的文档、向导和示例。

这确实是最短路径,而且是一个完整的工具包。

于 2013-05-23T04:06:08.903 回答
0

在我的公司中,我们想要的是一个 Apache TomEE 服务器,它使用 JAX-RS 将我们的 API 公开为 REST 服务。它易于设置且易于使用。

于 2013-05-22T23:43:32.273 回答
0

我对 Jersey 有很好的经验,它是 jax-ws 的参考实现。它支持 jax-ws 注释,并且易于使用。

于 2013-05-26T14:53:37.343 回答
0

作为顾问,我因解决问题而获得报酬。我发现 Espresso Logic 是我提供 JSON/REST API 的最快方式。它在 Tomcat 基础上运行,并且可以轻松地部署在本地、Elastic Beanstalk 或 Microsoft Azure 上。它连接到所有主要的 SQL 数据库,并为所有表、视图、存储过程和关系(用于构建更复杂的文档样式资源)提供即时 REST API。它具有用于管理的 HTML Studio 和 Node.JS 命令行。最好的功能是用于公式、推导和验证的声明性逻辑(如电子表格)。可以使用 JavaScript 和 Java 插件库来扩展逻辑。我花时间编写 JavaScript 解决方案,让 Espresso 完成繁重的 REST 分页、乐观锁定、SQL 查询优化、和多表事务逻辑。全面披露——我认识他们 25 年了,这是我见过的最好的改变游戏规则的技术。看看:www.espressologic.com

于 2015-06-14T23:41:53.667 回答
0

按照https://stackoverflow.com/a/3891380/1497139加速使用Jersey框架

我们(BITPlan - 我的公司)创建了以下开源项目:

  1. https://github.com/BITPlan/com.bitplan.simplerest
  2. https://github.com/BITPlan/com.bitplan.simplerest-api
  3. https://github.com/BITPlan/com.bitplan.simplerest-example

请参阅下面的代码示例如何设置:

  1. 服务器
  2. 一些要使用的应用程序内容(用户)
  3. 一些暴露内容的资源(UserResource)
  4. 一个测试用例表明一切正常

测试示例

package com.bitplan.simplerest.example;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import com.bitplan.rest.RestServer;
import com.bitplan.rest.test.TestRestServer;

/**
 * test the example Server
 * @author wf
 *
 */
public class TestExampleServer extends TestRestServer {
  boolean debug=true;
  @Before
  public void initServer() throws Exception {
    startServer();
  }

  @Override
  public RestServer createServer() throws Exception {
    RestServer result = new ExampleServer();
    return result;
  }

  @Test
  public void testExampleServer() throws Exception {
    String userXml=getResponseString("application/xml", "/example/user");
    if (debug)
      System.out.println(userXml);
    String expected="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><user><name>Doe</name><firstname>John</firstname><email>john@doe.org</email></user>";
    assertEquals(expected,userXml);
    String userJson=getResponseString("application/json", "/example/user");
    if (debug)
      System.out.println(userJson);
    String expectedJson="{\"name\":\"Doe\",\"firstname\":\"John\",\"email\":\"john@doe.org\"}";
    assertEquals(expectedJson,userJson);

  }

}

示例服务器

package com.bitplan.simplerest.example;

import com.bitplan.rest.RestServerImpl;

/**
 * an Example Server
 * @author wf
 *
 */
public class ExampleServer extends RestServerImpl { 

  /**
   * construct Example Server
   * setting defaults
   * @throws Exception 
   */
  public ExampleServer() throws Exception {
    // listen to whole network
    settings.setHost("0.0.0.0");
    // listen on given port
    settings.setPort(8111);
    // add the default path
    settings.setContextPath("/example");
    // add a static handler
    settings.addClassPathHandler("/", "/static/");
    // setup resources from the given packages
    String packages="com.bitplan.simplerest.example.resources;";
    settings.setPackages(packages);
   }

  /**
   * start Server
   * 
   * @param args
   * @throws Exception
   */
   public static void main(String[] args) throws Exception {
     ExampleServer rs=new ExampleServer();
     rs.settings.parseArguments(args);
     rs.startWebServer();
   } // main

}

用户

package com.bitplan.simplerest.example;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * example class
 */
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
  public String name;
  public String firstname;
  public String email;

}

用户资源

package com.bitplan.simplerest.example.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.bitplan.simplerest.example.User;


@Path("/user")
public class UserResource {
  @GET
  public User getUser() {
    User user=new User();
    user.name="Doe";
    user.firstname="John";
    user.email="john@doe.org";
    return user;
  }
}
于 2016-06-18T07:33:34.983 回答
0

我想建议以下方法来编写基于 REST 的 Web 服务。下面的“脚本”将指导您使用KikahaUndertow创建一个非常简单、轻量级的 Web 项目。下面的方法与 Ryan Stewart 提供的基于 JAXRS 的示例非常相似,但由于 Undertow 的架构(Undertow非常快),它具有更高的性能和更少的占用空间。

  1. 使用 Kikaha 的命令行工具创建一个存根项目:

    kikaha 项目创建 2.0 --name=my-app

  2. 尽管上面的命令为您带来了几个开箱即用的 REST API 类,但您可以创建自己的实体类来代表您的业务规则,如下所示。

用户.java

import lombok.*;

@Getter
@Setter
public class User {
    @NonNull Long id;
    @NonNull String name;
}
  1. 创建一个路由类。它将方法公开为 REST 端点。

用户资源.java

import lombok.*;
import kikaha.urouting.api.*;
import javax.inject.*;

@Singleton
@Path("user")
@Consumes( Mimes.JSON )
@Produces( Mimes.JSON )
public class UserResource {

    User savedUser;

    @POST
    public Response saveUser( User user ){
        if ( user.getName().isEmpty() )
            return DefaultResponses.preconditionFailed()
                    .entity("Name is blank");

        savedUser = user;
        return DefaultResponses.ok();
    }

    @GET
    public User getUser(){
        return savedUser;
    }
}
  1. 通过命令行运行您的 5Mb 项目:

    kikaha 运行应用程序

免责声明:我参与了 Kikaha 的开发,并从第一个版本开始植入了许多 Undertow 项目。

于 2015-09-14T12:46:29.367 回答
0

所有答案都适用于在本地容器中使用 Java。如果您正在考虑支持 Java(和类似 Java 的扩展)的云环境,您可能只需一个类似的就可以做到这一点。

Raimme 平台提供了一个方便的@Rest 注解。您只需设置 URL,您的 REST 服务就会自动公开:

@Rest(url = "customer/list")
@ResponseBody
public String getCustomer()
{
    return "[]";
}

此处更详细地描述了整个功能:http ://raimme.com/devcenter?questionId=1cg000000000g

于 2017-03-16T13:54:39.250 回答