RESTful MySQL /术语/传递参数/返回Ints和Doubles

Gre*_*mbs 9 java mysql rest json netbeans

因此,在尝试创建MySQL数据库的RESTful前端时,我简要地查看了phprestql(简单而简单,但过于简单),现在我正在尝试将其构建到NetBeans的教程中.我已经完成了基本教程,并且正好使用我的数据库.但是,我正在试图弄清楚如何定制它.

  1. JSON中的所有结果似乎都是字符串,即使MySQL表中的属性是Big Ints,Ints和Doubles.这些类型似乎也在netbeans源中正确设置.但是,JSON将所有内容都返回为字符串.有什么想法可以解决这个问题?(同样,我只是在上面的教程中工作,尽管我的数据库.)

  2. 我还试图弄清楚如何在URI中实现其他参数,以进一步细化数据库结果.(http:// localhost/the_db/people_table /?gender_property = male&updated_property = 2011-01-18)...将返回符合这些条件的所有人行.我的部分问题是我甚至不确定这种功能的正确术语,所以它使得查找示例和教程变得有点困难.

  3. 这可能与前一项有关,但我也想使用URI"深入"到表/行/属性中以返回单个值(以JSON格式)......(http:// localhost/the_db/people_table/42/lastname)...将返回{"Jones"}

问题的一部分是我几乎不知道Python中的Ruby.我非常熟悉Objective-C,PHP和Perl中的东西.但是,使用那些快速简便的Restful MySQL服务的教程似乎并不常见或流行.

[编辑]

在某种程度上这有助于回答问题#1,我附加了一些java方法来指示如何设置/检索数值属性...从我可以告诉实际的JSON生成是由某些库自动生成的.我在这里看不到它:

/** in the MySQL CommitteeObj table, the committeeId is set as follows */
/* `committeeId` bigint(11) NOT NULL auto_increment */

/** in committee.java */
public class committee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "committeeId")
    private BigInteger committeeId;
//.....
}

public committee(BigInteger committeeId) {
    this.committeeId = committeeId;
}

@Override
    public String toString() {
        return "texlege.committee[committeeId=" + committeeId + "]";
    }

/** in committeeConverter.java */

@XmlElement
public BigInteger getCommitteeId() {
    return (expandLevel > 0) ? entity.getCommitteeId() : null;
}

public void setCommitteeId(BigInteger value) {
    entity.setCommitteeId(value);
}

/** in committeeResource.java */

@GET
    @Produces({"application/json"})
    public committeeConverter get(@QueryParam("expandLevel")
                                  @DefaultValue("1")
    int expandLevel) {
        return new committeeConverter(getEntity(), uriInfo.getAbsolutePath(), expandLevel);
    }

protected committee getEntity() {
        try {
            return (committee) em.createQuery("SELECT e FROM committee e where e.committeeId = :committeeId").setParameter("committeeId", id).getSingleResult();
        } catch (NoResultException ex) {
            throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是来自特定委员会的查询的输出.请注意,committeeId,committeeType和parentId属性明显缺少JSON编号:

{
    "@uri":"http://localhost:8080/TexLegeRest/rest/committees/2735/",
    "clerk":"Amy Peterson",
    "committeeId":"2735",
    "committeeName":"Appropriations",
    "committeeType":"1",
    "parentId":"-1",
    "updated":"2011-02-20T00:00:00-06:00",
}
Run Code Online (Sandbox Code Playgroud)

and*_*dyb 6

简而言之,这个答案可能不是您正在寻找的,因为它与NetBeans无关.但是,它确实提供了一种不同的方式来为MySQL数据库提供RESTful接口.

上传了一个包含4个Java文件,2个XML文件和1个文本文件的zip文件来支持这个解决方案,否则答案会很长.

简而言之,这是一个Maven/Java/Spring/Hibernate/MySQL解决方案,原因是我最近一直在使用这个架构,并且发现它非常简单和强大,只需要转换SQL↔JSON!

这个解决方案还使用了一些其他工具,比如Maven来编译/打包/部署而不是IDE,在我看来,这会消除一定程度的复杂性,但可能会让一些爱好IDE的人失望.

系统配置

首先,如果您还没有Java和Maven,首先需要下载并解压缩/安装Java和Maven.我也会假设Windows,主要是因为我正在使用它.我在以下位置安装了上述应用程序:

c:\apps\java\jdk1.6.0_24
c:\apps\apache-maven-3.0.3
Run Code Online (Sandbox Code Playgroud)

由于此解决方案中没有IDE,因此可以从命令行构建和运行应用程序.这里有很少的配置,所以只需执行以下操作来设置一些环境变量:

set JAVA_HOME=c:\apps\java\jdk1.6.0_24 Enter

set M2_HOME=c:\apps\apache-maven-3.0.3 Enter

set PATH=%PATH%;%M2_HOME%\bin;%JAVA_HOME%\bin Enter

mvn --version然后可以使用键入来验证是否已正确安装和找到Java和Maven.

项目创建

为您的源创建一个目录,让我们使用 c:\src\project1

再次在命令行上,导航到该目录并执行:

mvn archetype:generate -DgroupId=my.group -DartifactId=project1 -DarchetypeArtifactId=maven-archetype-quickstart
Run Code Online (Sandbox Code Playgroud)

Maven将下载一些标准库并最终提示您"定义属性值'版本':" - 只是Enter为了继续.然后,Maven会要求您确认项目设置,然后Enter再次点击确认.最终将得到一个目录结构,您可以在其中找到一个pom.xml文件和两个Java文件.项目对象模型(POM)文件告诉Maven如何构建/测试/打包/部署(以及更多)您的项目.您需要向该文件添加一些库,以便我们可以使用Spring,JSON,Jetty和其他功能.因此,编辑pom.xml将以下内容添加到XML结构中:

<project>元素下(即作为元素的兄弟<url>)添加:

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <spring.version>3.0.5.RELEASE</spring.version>
</properties>
<repositories>
  <repository>
    <id>JBoss</id>
    <url>https://repository.jboss.org/nexus/content/groups/public/</url>
    <releases>
      <enabled>true</enabled>
      <updatePolicy>always</updatePolicy>
      <checksumPolicy>warn</checksumPolicy>
    </releases>
  </repository>
</repositories>
Run Code Online (Sandbox Code Playgroud)

<dependencies>元素下添加上面链接的zip文件中的dependencies.txt文件的内容.这些更改将允许Maven找到最新的HibernateSpring库,这些库并不总是存在于默认的Maven存储库以及其他库中,例如HSQLDB - 用于测试此示例和JSON↔Java转换的内存数据库.

同样在<project>元素下(我在</dependencies>元素之后添加了这个)添加以下内容:

<build>
  <plugins>
    <plugin>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>maven-jetty-plugin</artifactId>
      <version>6.1.26</version>
      <configuration>
        <contextPath>/${project.artifactId}</contextPath>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <webXml>${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml</webXml>
      </configuration>
    </plugin>
  </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

这是我们将用于运行.war您要构建的文件的嵌入式Web服务器,这将导致我们最终的更改pom.xml... <packaging>文件顶部附近的元素需要更改为war而不是jar.

再次在命令行上,导航到刚刚创建的项目目录(可能是pom.xml cd project1)并键入mvn compile.Maven应该下载我们刚刚在POM中添加的所有新库,并希望编译时没有错误.现在我们需要配置Spring来连接所有RESTful URL和bean并配置Web应用程序本身.

创建名为下/ SRC /主2个新的目录resourceswebapp/WEB-INF.您的目录结构现在应如下所示:

src
src/main
src/main/java
src/main/resources
src/main/webapp/WEB-INF
Run Code Online (Sandbox Code Playgroud)

resources添加applicationContext.xml从zip文件调用的文件.所述的ApplicationContext是应用程序的配置.

WEB-INF目录中添加web.xml从zip文件调用的文件.在web.xml描述了一个Web容器(如Tomcat或在我们的例子码头)应该如何部署应用程序.

现在我们需要添加一些代码!这个zip文件包含4个类,而不是在这里添加代码并使这个答案比现有的更长.只需将它们复制到src/main/java/my/group目录中,覆盖App.java过程即可.

编译和执行

这是您应该交叉的地方......因为您应该能够使用mvn compile编译类,然后成功mvn jetty:run-war运行带有应用程序war文件的Web服务器.如果启动应用程序时没有错误,应该有一些看起来像INFO: Mapped URL path [/people] onto handler 'app'Jetty初始化完成的日志记录.

测试REST接口

现在我们可以测试RESTful URL.我建议使用Firefox 的海报插件(虽然与Firefox 4不兼容),所以安装它,我们可以使用它在project1网络应用程序上执行PUT和GET请求.安装完成后,选择工具→海报或Ctrl+ Alt+ P.

首先,由于我们使用Spring内容协商(向下滚动到该Content Negotiation部分),您需要配置Poster以添加正确的内容类型.只需添加application/json到此字段即可.要添加一个到我们的数据库,只需添加

{"firstName" : "foo", "lastName" : "bar"}
Run Code Online (Sandbox Code Playgroud)

到身体(这是海报插件中的大区域)并使用PUT按钮.您应该从Web应用程序获得响应,并查看命令窗口中的日志记录.答复应该是:

{"name":"foo bar","id":1,"height":1.8}
Run Code Online (Sandbox Code Playgroud)

这是有效的JSON,你可以看到整数和双精度出现得很好.如果您查看zip文件中的Person.java类,您可以看到firstName并且lastName是实际类成员的名称,这些名称与JSON键的名称相匹配PUT.我已经为这些添加了一个@JsonIgnore 注释,并创建了一个不同的@JsonProperty来返回全名.实际上你可能不会这样做,否则很难只更新名字或姓氏,但在这个例子中,我只是用它来表明你完全控制了返回的JSON实体及其名称/值.另请注意,Person类有一个硬编码的Double(高度成员),用于演示数字是否正确序列化为JSON.

然后,您可以通过将URL更改为并使用按钮来检索人员1,http://localhost:8080/project1/people/1而该GET按钮只返回相同的JSON.

交换HSQLDB for MySQL

您可能已经注意到目前为止还没有MySQL数据库.您需要将一些配置更改为指向MySQL数据库,而不是直到现在使用的内存中HSQL数据库."dataSource"bean属性应该像这样更新:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
  p:driverClassName="com.mysql.jdbc.Driver"
  p:url="jdbc:mysql://localhost:3306/name_of_your_database_instance"
  p:username="your_database_username"
  p:password="your_database_password"/>
Run Code Online (Sandbox Code Playgroud)

您需要在何处指定数据库的连接详细信息.

最后休眠方言需要更新是MySQL的一个,所以更换org.hibernate.dialect.HSQLDialect

<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
Run Code Online (Sandbox Code Playgroud)

applicationContext.xml文件中.

请注意,当Hibernate配置了以下属性时<prop key="hibernate.hbm2ddl.auto">create</prop>,它将在Web应用程序启动时销毁数据库,因为Hibernate正在扫描Person类并从@Table,@ Entity和@Column(和其他)注释创建表.

请注意,遗憾的是我没有测试过最后一部分,因为我没有安装MySQL,但希望它能够正常工作.

回答你的问题(或不回答)

1)不知道,抱歉.它看起来只是一个转换/序列化问题,可以通过查看教程中使用的bean和检查其文档来解决.

2)和3)使用上面的解决方案,您可以根据需要添加任意数量的路径变量,例如

@RequestMapping(value = "/people/gender/{gender}/updated/{lastUpdated}", method = RequestMethod.GET)
@ResponseBody
public Person findByGenderAndUpdated(@PathVariable String gender, @PathVariable String lastUpdated) {}
Run Code Online (Sandbox Code Playgroud)

创建API以公开各个属性可能不切实际.通过URL返回完整资源更实用,然后让下游组件从Person JSON对象中挑选lastName,如果这就是它所需的全部内容.但是,如果有大量数据,我可以看到需要一个Person的简化JSON表示.即,从带宽的角度来看,它可以更有效地排除某些大数据属性.

您必须自己为每个组合实现这些方法.这有效地构成了您的RESTful API.如果您需要创建一个文档来描述您的API,那么Atlassian指南就写得非常好.

摘要

这个解决方案有很多变化,在实践中你应该把类放在一个更好的目录结构(模型,视图,控制器)中,并创建一些Java类模板来处理持久性,因为所有模型都需要"保存","找到"方法".

我希望这个解决方案对某人有用:-)