RESTful MySQL / Терминология / Передача параметров / Возвращаемые числа и двойники - PullRequest
9 голосов
/ 06 марта 2011

Итак, пытаясь создать RESTful-интерфейс для базы данных MySQL, я кратко рассмотрел phprestql (легко и просто, но просто слишком просто) и сейчас пытаюсь его построить. учебное руководство по NetBeans .Я закончил базовый урок и отлично работаю с базой данных.Тем не менее, я пытаюсь выяснить, как его немного настроить.

  1. Все результаты в JSON кажутся строками, даже если в свойствах таблицы MySQL есть Big Ints, Intsи удваивается.Типы также, кажется, установлены правильно в пределах источников 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) ... вернул бы {"Джонс"}

Часть проблемы в том, что я едва знаю Java из Ruby из Python. IЯ довольно хорошо разбираюсь в технологиях Objective-C, PHP и Perl, однако учебники для быстрых и простых служб Restful MySQL с ними не кажутся очень популярными или распространенными.

[EDIT]

В той степени, в которой это помогает ответить на вопрос № 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);
        }
    }
}

А вот вывод из запроса конкретного комитета.Обратите внимание на явное отсутствие чисел JSON для свойств CommitteeId, CommitteeType и parentId:

{
    "@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",
}

Ответы [ 2 ]

6 голосов
/ 22 марта 2011

Короче говоря, этот ответ может совсем не соответствовать тому, что вы ищете, поскольку он не имеет ничего общего с NetBeans.Однако он предоставляет другой способ делать то, что вы хотите, предоставляя RESTful-интерфейс для базы данных MySQL.

У меня есть загруженный zip-файл с 4 файлами Java, 2 файлами XML и 1текстовый файл для поддержки этого решения, в противном случае ответ был бы очень длинным.

Короче говоря, это решение Maven / Java / Spring / Hibernate / MySQL, причина в том, что я недавно использовал эту архитектуруи нашел довольно простым и мощным сделать то, что на самом деле просто конвертирует SQL ↔ JSON!

Это решение также использует несколько других инструментов, таких как Maven, для компиляции / упаковки / развертывания, а не IDE, которая, по моему мнению, удаляетуровень сложности, но может оттолкнуть нескольких людей, любящих IDE.

Конфигурация системы

Итак, во-первых, вам нужно будет загрузить и распаковать / установить Java и Maven, если у вас нетте уже.Я также предполагаю Windows, главным образом потому, что это то, что я сейчас использую.Я установил вышеуказанные приложения в следующих местах:

c:\apps\java\jdk1.6.0_24
c:\apps\apache-maven-3.0.3

Поскольку в этом решении нет среды 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 Введите

Ввод mvn --version может использоваться для проверки правильности установки и обнаружения Java и Maven.

Создание проекта

Создайте каталог для вашего источника, давайте использовать c:\src\project1

В командной строке снова перейдите к этому каталогу и выполните:

mvn archetype:generate -DgroupId=my.group -DartifactId=project1 -DarchetypeArtifactId=maven-archetype-quickstart

Mavenзагрузит некоторые стандартные библиотеки и в конечном итоге предложит вам «Определить значение для свойства« версия »:» - просто Введите , чтобы продолжить.Затем Maven попросит вас подтвердить настройки проекта, поэтому просто нажмите Введите еще раз для подтверждения.В итоге вы получите структуру каталогов, в которой вы найдете файл 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>

Под *Элемент 1059 * добавляет содержимое файла dependencies.txt из zip-файла, указанного выше.Эти изменения позволят Maven найти новейшие библиотеки Hibernate и Spring , которые не всегда присутствуют в репозиториях 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>

Это встроенный веб-сервер, который мы будем использовать для запуска файла .war, который вы собираетесь создать, что приведет нас к окончательному изменению элемента pom.xml<packaging> в верхней частифайл должен быть изменен на war вместо jar.

В командной строке снова перейдите в каталог проекта, который вы только что создали, где находится pom.xml (вероятно, cd project1), и введите mvn compile.Maven должен загрузить все новые библиотеки, которые мы только что добавили в POM, и, надеюсь, скомпилировать их без ошибок.Теперь нам нужно просто сконфигурировать Spring для подключения всех RESTful URL и bean-компонентов и настроить само веб-приложение.

Создайте 2 новых каталога в / src / main с именами resources и webapp/WEB-INF.Ваша структура каталогов теперь должна выглядеть следующим образом:

src
src/main
src/main/java
src/main/resources
src/main/webapp/WEB-INF

В resources добавьте файл с именем applicationContext.xml из zip-файла. ApplicationContext - это конфигурация для приложения.

В каталоге WEB-INF добавьте файл с именем web.xml из zip-файла.web.xml описывает, как веб-контейнер (например, Tomcat или, в нашем случае, Jetty) должен развертывать приложение.

Теперь нам нужно добавить код!Вместо того, чтобы добавлять код здесь и делать этот ответ длиннее, чем он есть, zip-файл содержит 4 класса.Просто скопируйте их в каталог src/main/java/my/group, переписав при этом App.java.

Компиляция и выполнение

Это то место, где вы должны скрестить пальцы ... как вы должны уметь использовать mvn compile чтобы скомпилировать классы, а затем в случае успеха mvn jetty:run-war запустить веб-сервер с файлом war приложения.Если при запуске приложения нет ошибок, должна быть некоторая запись в журнале, которая выглядит как INFO: Mapped URL path [/people] onto handler 'app' по завершении инициализации Jetty.

Тестирование интерфейса REST

Теперь мы можем протестировать RESTfulURL-адрес.Я рекомендую использовать Poster addon для Firefox (хотя и не совместим с Firefox 4), поэтому установите его, и мы сможем использовать его для выполнения запросов PUT и GET в веб-приложении project1.После установки выберите Инструменты → Плакат или Ctrl + Alt + P .

Во-первых, поскольку мы используем согласование содержимого Spring (прокрутите вниз до раздела Content Negotiation), вам нужно настроить Poster для добавления правильного типа контента.Просто добавьте application/json в это поле.Чтобы добавить person в нашу базу данных, просто добавьте

{"firstName" : "foo", "lastName" : "bar"}

к телу (это большая область в дополнении Poster) и используйте кнопку PUT ,Вы должны получить ответ от веб-приложения и увидеть вход в командном окне.Ответ должен быть следующим:

{"name":"foo bar","id":1,"height":1.8}

Это допустимый JSON, и вы можете видеть, что целые и двойные числа выглядят просто отлично.Если вы посмотрите на класс Person.java из zip-файла, вы увидите, что firstName и lastName - это имена фактических членов класса, которые соответствуют именам ключей JSON, которые были PUT.Я добавил к ним аннотацию @JsonIgnore и создал другой @JsonProperty, чтобы вместо этого вернуть полное имя.На практике вы, вероятно, не сделали бы этого, иначе было бы трудно обновить только имя или фамилию, но в этом примере я просто использую его, чтобы показать, что у вас есть полный контроль над возвращаемыми сущностями JSON и их именами / значениями.Также обратите внимание, что класс Person имеет жестко запрограммированный тип Double (член height ), чтобы продемонстрировать, что числа правильно сериализованы в JSON.

Затем можно получить person 1 изменив URL-адрес на http://localhost:8080/project1/people/1 и используя вместо него кнопку GET , которая просто возвращает тот же JSON.

Замена HSQLDB для MySQL

Возможно, вы заметили, чтобазы данных MySQL пока нет.Вам нужно будет изменить некоторые параметры конфигурации, чтобы они указывали на базу данных MySQL вместо базы данных HSQL в памяти, которая использовалась до сих пор.Свойства bean-компонента «dataSource» должны быть обновлены следующим образом:

<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"/>

, где необходимо указать детали подключения к вашей базе данных.

Наконец, диалект гибернации требует обновления, чтобы быть MySQL.поэтому замените org.hibernate.dialect.HSQLDialect на

<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>

в файле applicationContext.xml.

Имейте в виду , что когда Hibernate настроен со следующим свойством <prop key="hibernate.hbm2ddl.auto">create</prop>при запуске веб-приложения база данных будет уничтожена, поскольку Hibernate сканирует класс Person и создает таблицу из аннотаций @Table, @Entity и @Column (и других).

Обратите внимание, чток сожалению, я не тестировал эту последнюю часть, так как у меня не установлен MySQL, но, надеюсь, он должен работать.

Отвечая на ваши вопросы (или нет)

1) Понятия не имею, извините.Это похоже на проблему преобразования / сериализации, которую, вероятно, можно решить, посмотрев, какие компоненты используются в руководстве, и проверив их документацию.

2) и 3) С помощью приведенного выше решения вы можете добавить как можно больше переменных путикак вам требуется, например

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

Возможно, нецелесообразно создавать API для предоставления отдельных свойств.Возвращать полные ресурсы по вашим URL-адресам более практично, а затем просто позволить нижестоящему компоненту выбрать lastName из Person JSON-объекта, если это все, что ему нужно.Однако я мог видеть необходимость в сокращенном JSON-представлении Person, если данных много.т. е. с точки зрения пропускной способности более эффективно исключать некоторые большие свойства данных.

Вам придется самостоятельно реализовать эти методы для каждой комбинации.Это фактически составляет ваш RESTful API.Если вам нужно создать документ для описания вашего API, то Atlassian руководящие принципы написаны очень хорошо.

Резюме

Существует много вариантов этого решения, и на практике выследует поместить классы в лучшую структуру каталогов (модель, представление, контроллер) и создать несколько шаблонов классов Java для обработки персистентности, поскольку всем моделям, вероятно, понадобится метод "save", "find", например.

Надеюсь, это решение кому-нибудь пригодится: -)

3 голосов
/ 09 марта 2011

Все результаты в JSON выглядят как строки, хотя в таблице свойств MySQL есть большие, двойные и двойные значения.Типы также, кажется, установлены правильно в пределах источников NetBeans.Тем не менее, JSON возвращает все в виде строк.Есть идеи, где это решить?(Опять же, я просто работаю из учебника выше, хотя и с моей БД.)

Числа в JSON будут без кавычек.Для бывшего {"персона": {"имя": "Фред", "возраст": 24}}.Поэтому анализатор JSON должен иметь возможность обрабатывать его как числовой.

Я также пытаюсь выяснить, как я могу реализовать дополнительные параметры в URI для дальнейшего уточнения результатов БД.(http://localhost/the_db/people_table/?gender_property=male&updated_property=2011-01-18) ... вернул бы все строки людей, которые соответствуют этим критериям. Часть моей проблемы в том, что я даже не уверен в правильной терминологии для такого рода функций, поэтому затрудняется поиск примеров и учебных пособий.

Это так называемые параметры запроса. Они очень полезны, особенно когда в вашем запросе много необязательных параметров

Это может быть связано с предыдущимitem, но я также хотел бы использовать URI для «детализации» в таблице / строке / свойстве для возврата отдельных значений (в JSON) ... (http://localhost/the_db/people_table/42/lastname) ... вернул бы {"Jones"}

Здесь можно использовать параметры запроса. Если конкретный параметр передается через url, он будет установлен или будет нулевым. Проверьте нулевое условие каждого параметра запроса и создайте предложение where на основе параметров.которые не равны нулю. Это даст требуемый результат.

ОБНОВЛЕНИЕ: Если возвращение чисел в виде строки является единственной проблемой, с которой вы столкнулись, добавьте следующее к web.xml.Это сделало бы поддержку pojo.Это вернет числа в виде чисел.

 <init-param>
   <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
   <param-value>true</param-value>
 </init-param>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...