Во второй части этой статьи мы собираемся создать управляемый данными веб-сервис, который будет возвращать JSON и XML клиенту, а затем с помощью jQuery добавить новый элемент в базу данных и отобразить его на нашей странице.
В первой части мы рассмотрели создание простых веб-сервисов, а теперь мы собираемся сделать что-то более практичное и интересное. Мы начнем с того места, где мы остановились, с исходным кодом, как это было в конце части 1, которую вы можете скачать отсюда ( restwebdemo_pt1 ), если хотите следовать. Если нет, окончательный исходный код можно скачать отсюда ( restwebdemo_pt2 ).
- Прежде всего, мы собираемся изменить менеджера сущностей, который доступен для внедрения в область запроса. Для этого откройте DataRepositoryProducer.java и измените аннотацию @ConversationScoped в методе getEntityManager () на @RequestScoped. Причина этого задокументирована в разделе «Меньше разговоров» .
- Далее мы собираемся создать простой дао для объектов Course, и единственная причина сделать это — продемонстрировать интеграцию CDI и способность наслоить ваш код. Создайте новый класс с именем CourseDao со следующим кодом.
package org.fluttercode.restwebdemo.bean;
@Stateless
@LocalBean
public class CourseDao {
@Inject @DataRepository
private EntityManager entityManager;
public void save(Course course) {
entityManager.persist(course);
}
public Course update(Course course) {
return entityManager.merge(course);
}
public Course find(Long id) {
return entityManager.find(Course.class, id);
}
}Это просто внедряет entityManager и использует его для поиска, сохранения и обновления объектов курса.
- Теперь создайте новый компонент CourseService, который будет обрабатывать веб-сервисы. Для начала мы хотим сделать его EJB без учета состояния и ввести курс Dao. Мы собираемся начать с повторной реализации метода, чтобы вернуть имя курса для данного идентификатора.
@Path("courseName/{id}")
@GET
public String getCourseName(@PathParam("id") Long id) {
Course course = courseDao.find(id);
if (course == null) {
return "Course not found";
} else {
return course.getTitle();
}
}
Чтобы увидеть этот метод в действии, разверните приложение и перейдите по адресу http: // localhost: 8080 / restwebdemo / rest / course / courseName / 126 . Теперь мы знаем, что все работает и подключены вместе, мы можем посмотреть на добавление некоторых новых функций.
Давайте начнем с возврата курса с заданным идентификатором из сервиса. Это довольно просто, учитывая то, что мы уже знаем. Теперь единственное, что нужно определить — это какой формат вернуть объект и преобразовать его в этот тип. К счастью, Java EE уже предоставляет JAXB, который может взять граф объектов и преобразовать его в XML для нас, пока мы аннотируем классы аннотациями, чтобы реализация JAXB знала, как преобразовать его. Те же самые аннотации могут использоваться автором тела, который обрабатывает JSON.
Сначала мы аннотируем курс и сделаем пару изменений, которые нам нужны. Далее мы создадим методы для возврата объекта Cource из сервиса в формате XML или JSON.
- Откройте класс Course и добавьте в него следующие аннотации.
@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Course extends BaseEntity {
...
...
}Это говорит процессору JAXB, что этот класс можно сериализовать и получить доступ к значениям, используя поля в классе. Это также означает, что любые другие аннотации, которые мы хотим добавить для управления сериализацией, должны применяться к полям.
Это простой пример, поэтому мы не хотим сериализовать учитель или зарегистрированные свойства, которые мы можем сделать, пометив их атрибутами @XmlTransient. Также удалите аннотацию @NotNull из атрибута учителя, так как она понадобится нам позже. Следующий код показывает поля с аннотациями JAXB и JPA. JAXB (как JPA) использует соглашения по умолчанию для полей, которые не имеют аннотаций:
@Column(length = 32, nullable = false)
@Size(max = 32)
@NotEmpty(message = "title is required")
private String title;
@Column(length = 8, nullable = false)
@Size(max = 8 )
@NotEmpty(message = "code is required")
private String code;
@ManyToOne(fetch = FetchType.LAZY)
@XmlTransient
private Teacher teacher;
@ManyToMany(mappedBy = "enrolled")
@XmlTransient
private List<Student> students = new ArrayList<Student>();Мы просто используем простую модель JAXB для примера, поэтому мы не включаем классы Teacher и Student.
- Теперь в нашем классе CourseService мы создадим методы для возврата сущности курса и создадим один для JSON и один для XML.
@Path("find/{id}/xml")
@GET
@Produces(MediaType.APPLICATION_XML)
public Course getCourseAsXml(@PathParam("id") Long id) {
return courseDao.find(id);
}
@Path("find/{id}/json")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Course getCourseAsJson(@PathParam("id") Long id) {
return courseDao.find(id);
}
(примечание: на этом этапе мне пришлось переключиться на использование Hibernate в качестве поставщика JPA, поскольку JAXB не понравился интерфейс EclipseLink, используемый для передачи свойств. Это можно сделать с помощью инструмента обновления Glassfish).
Если вы повторно развернете приложение и перейдете по адресу http: // localhost: 8080 / restwebdemo / rest / course / find / 1 / json, вам будет предложено сохранить файл, или он отобразит текст, но содержимое должно быть примерно таким: :
{"createdOn":"2010-08-27T16:36:57.015-04:00",
"id":"1",
"modifiedOn":"2010-08-27T16:36:57.015-04:00",
"title":"Computing for Beginners",
"code":"CS101"}
или если вы перейдете по адресу http: // localhost: 8080 / restwebdemo / rest / course / find / 1 / xml, вы получите версию XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<course>
<createdOn>2010-08-27T16:36:57.015-04:00</createdOn>
<id>1</id>
<modifiedOn>2010-08-27T16:36:57.015-04:00</modifiedOn>
<title>Computing for Beginners</title>
<code>CS101</code>
</course>
Теперь мы можем получить объекты из нашего веб-сервиса, мы должны посмотреть на создание объектов из сервиса. Мы добавляем новый метод, который принимает заголовок и значения кода, создает новый курс с этими значениями и сохраняет его с помощью courseDao.
@Path("create")
@PUT
@Produces(MediaType.APPLICATION_JSON)
public Course createCourse(@FormParam("title") String title,@FormParam("code") String code) {
Course course = new Course();
course.setTitle(title);
course.setCode(code);
courseDao.save(course);
return course;
}
Здесь я использовал аннотации FormParam для вставки значений формы в вызов метода. Вы заметите, что, используя соглашения REST, метод создания курса использует тип запроса PUT. Теперь давайте создадим страницу, чтобы ввести заголовок и код и создать курс. Обратите внимание, что наш метод возвращает созданный курс, чтобы мы могли вернуть курс обратно пользователю. Это, вероятно, не идеально, но подходит для демонстрации. Теперь давайте создадим новую HTML-страницу для ввода данных и вызова веб-службы для создания курса.
<html>
<head>
<title>Insert title here</title>
<script type="text/javascript"
src="http://localhost:8080/restwebdemo/jquery-1.4.min.js">
</script>
</head>
<body>
<div id="message"
style="display: none; background: #d0d0f0; padding: 12px">Message Div</div>
<form action="rest/course/create" method="POST">
<fieldset>
<legend>Create Course</legend>
<p>
Title<br />
<input id="title" /><br />
</p>
<p>
Code<br />
<input id="code" /><br />
</p>
<input type="submit" id="submit" />
</fieldset>
</form>
</body>
<script type="text/javascript">
//jquery pieces
$(document).ready(function() {
//change the submit button behaviouus.
$('#submit').click(function () {
var title = $("input#title").val();
var code = $("input#code").val();
params = "title="+title+"&code="+code;
//alert("posting form : "+data);
$.ajax({
type: "PUT",
url: "rest/course/create",
data: params,
success: function(result) {
showMessage("Created Course "+result.title+" with id "+result.id+" on "+result.createdOn);
}
});
return false;
});
});
function showMessage(msg) {
$('#message').html(msg);
$('#message').fadeIn('fast');
$('#message').delay(3000).fadeOut('slow');
}
</script>
</html>
Это выглядит много кода, но не совсем. Мы импортируем jquery, чтобы помочь нам опубликовать нашу форму, и мы создаем нашу форму с двумя полями. Мы используем JQuery для добавления обработчика событий, поэтому, когда вы нажимаете кнопку отправить, он упаковывает форму, вызывает наш веб-сервис с запросом типа PUT, получает возвращенный объект как объект JSON и отображает сообщение, используя значения из нового Экземпляр получен с сервера. Чтобы убедиться, что ваш курс был создан, перейдите на первую страницу, и вы должны увидеть его в списке.
Для этого поста, исходный код можно скачать с ( restwebdemo_pt2 ), просто распаковать его, использовать пакет mvn clean и развернуть войну на glassfish и использовать URL-адреса, упомянутые в статье.
С http://www.andygibson.net/blog/tutorial/simple-restful-services-in-glassfish-pt-2/