Статьи

ВОССТАНОВЛЕНИЕ приложения Openxava и клиента Vaadin


Цель этой статьи — предоставить REST-интерфейс для приложения Openxava (OX).

Это показывает, как

  • интегрировать двигатель джерси в сборку OX
  • расширить сущности JPA2 аннотациями JAXB и JAXRS
  • написать небольшой UC с методами, которые возвращают сообщение xml / json
  • Попробуй это
  • Создайте пример клиентского приложения Vaadin для этих служб REST.

Чтобы проиллюстрировать это, я возьму приложение Openxava, сгенерированное минутным проектом (
http://minuteproject.blogspot.com/2011/09/sql-select-to-web-application-in-couple.html ).

Интегрируем движок Джерси в сборку OX.

Интеграция с Jersey lib

Добавьте следующие библиотеки в ваш проект / web / WEB-INF / lib

  • jsr305-1.3.2.jar
  • Джерси-ядро-1,9-ea03.jar
  • Джерси-сервер-1,9-ea03.jar
  • asm-3.1.jar (хотя asm.jar поставляется с OX, эта версия используется)

Здесь зависимость от jersey-server-1.9-ea03.

В вашем проекте OX добавьте файл servlets.xml в / web / WEB-INF

   <servlet>
<servlet-name>petshop Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.cool.report</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>petshop Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Сборка Openxava берет то, что вы определили в файле servlets.xml, и вставляет его в файл web.xml.
В приведенном выше фрагменте указано следующее:

  • Движок Jersey проанализирует пакет для аннотации JAXRS в пакете «my.cool.report»
  • контекстный путь, используемый для REST, будет / rest / *

Интеграция JAXB и JAXRS

Добавьте аннотацию Jaxb и Jaxrs в OX jpa2-сущностях

Класс MyConferenceCoolReport

package my.cool.report.conference.domain.report;

import java.sql.*;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;

import javax.persistence.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.xml.bind.annotation.*;

import my.cool.report.conference.dto.report.*;

import org.openxava.annotations.*;
import org.openxava.jpa.*;


/**
*
* <p>Title: MyConferenceCoolReport</p>
*
* <p>Description: Domain Object describing a MyConferenceCoolReport entity</p>
*
*/
@Entity (name="MyConferenceCoolReport")
@Table (name="my_conference_cool_report")
@Views({
@View(
name="base",
members=
""
+ "firstName  ; "
+ "lastName  ; "
+ "email  ; "
+ "status  ; "
+ "addressStreet1  ; "
+ "addressStreet2  ; "
+ "countryCode  ; "
+ "conferenceName  ; "
+ "conferenceBeginDate  ; "
+ "conferenceEndDate  ; "
),
@View(
name="Create",
extendsView="base"
),
@View(
name="Update",
extendsView="base",
members=
 ""
),
@View(extendsView="base",
members=
 ""
),
@View(name="myConferenceCoolReportDEFAULT_VIEW",
members=
 " id ;"
+ "firstName  ; "
+ "lastName  ; "
+ "email  ; "
+ "status  ; "
+ "addressStreet1  ; "
+ "addressStreet2  ; "
+ "countryCode  ; "
+ "conferenceName  ; "
+ "conferenceBeginDate  ; "
+ "conferenceEndDate  ; "
)
})

@Tabs({
@Tab(
properties=
" firstName "
+",  lastName "
+",  email "
+",  status "
+",  addressStreet1 "
+",  addressStreet2 "
+",  countryCode "
+",  conferenceName "
+",  conferenceBeginDate "
+",  conferenceEndDate "
)
,
@Tab(
name = "MyConferenceCoolReportTab",
properties=
" firstName "
+",  lastName "
+",  email "
+",  status "
+",  addressStreet1 "
+",  addressStreet2 "
+",  countryCode "
+",  conferenceName "
+",  conferenceBeginDate "
+",  conferenceEndDate "
)
,
@Tab(
name = "MyConferenceCoolReportTabWithRef",
properties=
" firstName "
+",  lastName "
+",  email "
+",  status "
+",  addressStreet1 "
+",  addressStreet2 "
+",  countryCode "
+",  conferenceName "
+",  conferenceBeginDate "
+",  conferenceEndDate "
)
})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement
@Path ("/myreports")
public class MyConferenceCoolReport {

@Hidden @Id @Column(name="id" )
private Long id;

@Column(name="first_name",  length=255, nullable=false,  unique=false)
@Required
private String firstName;
@Column(name="last_name",  length=255, nullable=false,  unique=false)
@Required
private String lastName;
@Column(name="email",  length=255, nullable=false,  unique=false)
@Required
private String email;
@Column(name="status",  length=45, nullable=false,  unique=false)
@Required
private String status;
@Column(name="address_street1",  length=255,  nullable=true,  unique=false)
private String addressStreet1;
@Column(name="address_street2",  length=255,  nullable=true,  unique=false)
private String addressStreet2;
@Column(name="country_code",  length=45, nullable=false,  unique=false)
@Required
private String countryCode;
@Column(name="conference_name",  length=255, nullable=false,  unique=false)
@Required
private String conferenceName;
@Column(name="conference_begin_date",    nullable=true,  unique=false)
private Date conferenceBeginDate;
@Column(name="conference_end_date",    nullable=true,  unique=false)
private Date conferenceEndDate;

/**
* Default constructor
*/
public MyConferenceCoolReport() {
}

public Long getId() {
return id;
}

public void setId (Long id) {
this.id =  id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName (String firstName) {
this.firstName =  firstName;
}
public String getLastName() {
return lastName;
}

public void setLastName (String lastName) {
this.lastName =  lastName;
}
public String getEmail() {
return email;
}

public void setEmail (String email) {
this.email =  email;
}
public String getStatus() {
return status;
}

public void setStatus (String status) {
this.status =  status;
}
public String getAddressStreet1() {
return addressStreet1;
}

public void setAddressStreet1 (String addressStreet1) {
this.addressStreet1 =  addressStreet1;
}
public String getAddressStreet2() {
return addressStreet2;
}

public void setAddressStreet2 (String addressStreet2) {
this.addressStreet2 =  addressStreet2;
}
public String getCountryCode() {
return countryCode;
}

public void setCountryCode (String countryCode) {
this.countryCode =  countryCode;
}
public String getConferenceName() {
return conferenceName;
}

public void setConferenceName (String conferenceName) {
this.conferenceName =  conferenceName;
}
public Date getConferenceBeginDate() {
return conferenceBeginDate;
}

public void setConferenceBeginDate (Date conferenceBeginDate) {
this.conferenceBeginDate =  conferenceBeginDate;
}
public Date getConferenceEndDate() {
return conferenceEndDate;
}

public void setConferenceEndDate (Date conferenceEndDate) {
this.conferenceEndDate =  conferenceEndDate;
}

@Transient
@GET
@Path("{reportId}")
@Produces ({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public MyConferenceCoolReport findById (@PathParam ("reportId") Long reportId) {
EntityManager em = XPersistence.getManager();
MyConferenceCoolReport p = em.find(MyConferenceCoolReport.class, reportId);
return p;
}

@Transient
@GET
@QueryParam("{countryCode}")
@Produces ({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public MyConfReports find (@QueryParam ("countryCode") String countryCode) {
String q = null;
EntityManager em = XPersistence.getManager();
if (countryCode!=null) {
   q = "select m from MyConferenceCoolReport m where countryCode = '"+countryCode+"'";
} else
q = "select m from MyConferenceCoolReport m ";
Query query = em.createQuery(q);
List<myconferencecoolreport> l = query.getResultList();
MyConfReports m = new MyConfReports();
m.setMyCoolReport(l);
return m;
}

}

Аннотация сущностей
Предыдущий фрагмент указывает, что сущность MyConferenceCoolReport содержит временный метод (findById), используемый для операции REST GET и использующий параметр reportId для загрузки сущности. Он может быть возвращен в формате Xml или в формате Json.
Он также содержит метод find, который принимает параметр кода страны и возвращает DTO на основе класса MyConfReports.

package my.cool.report.conference.dto.report;
package my.cool.report.conference.dto.report;

import java.util.*;

import javax.xml.bind.annotation.*;

import my.cool.report.conference.domain.report.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement
public class MyConfReports {

private List<MyConferenceCoolReport> myCoolReport;

public MyConfReports () {
}

public List<MyConferenceCoolReport> getMyCoolReport() {
return myCoolReport;
}

public void setMyCoolReport(List<MyConferenceCoolReport> myCoolReport) {
this.myCoolReport = myCoolReport;
}

}

Развертывание
Используйте сборку муравья в своем проекте.
Примечание: не забудьте при использовании openxava с eclipse для установки «Автоматически строить» на вкладке «Проект».

Тестирование
Через браузер введите
http: // localhost: 8080 / conference / rest / myreports? CountryCode = BE, чтобы просмотреть все http: // localhost: 8080 / conference / rest / myreports /, которые он возвращает в формате XML.