(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Google Sitebricks для отличных Web-приложений

Источник: ibm

Пример Web-приложения на языке Java с использованием Maven, Sitebricks и Guice.

Sitebricks ― это новая среда разработки Web-приложений на языке Java™, которая пока существует в виде бета-версии. Вы можете спросить: "Зачем мне еще одна среда разработки?" С помощью Google Sitebricks можно быстро создать Web-приложение, с которым смогут работать другие. Среда Sitebricks построена поверх Guice. Она расширяет и распространяет многие принципы Guice на Web. Как и Guice, она активно использует аннотации для хранения конфигурации как части кода. Чтобы использовать Guice, не нужно создавать и редактировать большое количество XML-файлов. Sitebricks позволяет создавать гораздо более лаконичные Web-приложения. Код получается простым. Глядя на код Sitebricks, сразу понимаешь, что происходит. Sitebricks не ставит под угрозу безопасность или производительность типов.

В этой статье на примере конкретного Web-приложения рассматриваются возможности Sitebricks. Пример приложения Reviewr позволяет читать и писать ресторанные обзоры. Для хранения данных приложения мы будем использовать базу данных (но не станем тратить на это слишком много времени). Пример фокусируется на тех частях приложения, в которых используются возможности Sitebricks.

Загрузите код примера приложения Reviewr по ссылке, приведенной в таблице в конце статьи.

Предварительные требования

В разделе Ресурсы содержатся ссылки на программы, которые нам потребуются.
  • Sitebricks находится на стадии бета-версии; в этой статье используется версия 0.8.
  • В настоящее время самый простой способ работы с Sitebricks ― с помощью Maven. Для этой статьи используется Maven 2.0.9. Конечно, Maven потянет за собой все прочие зависимости, необходимые для Sitebricks, такие как Google Guice.
  • Sitebricks опирается на некоторые расширенные возможности Java, так что нам потребуется JDK 1.6. В этой статье применяется JDK 1.6.0_17.
  • Для установки примера приложения из этой статьи можно использовать Java-сервер Web-приложений, но это не обязательно. 
    Пример приложения включает в себя встроенный сервер Jetty, которые можно использовать для тестирования.

Guice применяется в Sitebricks и в примере приложения. Было бы полезно знакомство с Guice или другой средой внедрения зависимостей, такой как Spring.

Использование Maven для создания Sitebricks-приложения

Как и многие современные Java-среды, Sitebricks использует Maven. Для создания нового проекта многие среды используют систему архетипа Maven. Это же планируется и для Sitebricks, но на момент написания статьи еще не реализовано. Поэтому в примере применяется несколько более ручной подход. Мы будем следовать передовому опыту Maven и сначала создадим проект бизнес-логики, как показано в листинге 1.

Листинг 1. Создание проекта бизнес-логики с применением Maven

$ mvn archetype:create -DgroupId=org.developerworks.reviewr -DartifactId=reviewrMain
[INFO] Scanning for projects...

Код создает простую структуру проекта, характерную для Java-приложений, которая в конечном итоге будет упакована в файл JAR. Следующий шаг заключается в создании второго проекта, который будет Web-приложением, как показано ниже.

Листинг 2. Создание Web-приложения Java с использованием Maven

$ mvn archetype:create -DgroupId=org.developerworks.reviewr -
DartifactId=reviewrWeb -DarchetypeArtifactId=maven-archetype-webapp
[INFO] Scanning for projects...

Похоже на листинг 1, но на этот раз идентификатором архетипа служит maven-archetype-webapp. Это основной архетип в Maven, который создает базовый проект Web-приложения Java. Теперь, когда проекты созданы, откроем их файлы pom и добавим Sitebricks. Сначала сделаем это для основного проекта бизнес-логики, как показано в листинге 3.

Листинг 3. Файл pom.xml основного проекта.

<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>org.developerworks.reviewr</groupId>
    <artifactId>reviewrMain</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>reviewrMain</name>
    <url>http://maven.apache.org</url>
    <repositories>
        <repository>
            <id>sonatype-google-snapshots</id>
            <name>Sonatype Google Snapshots Repository</name>
            <url>http://oss.sonatype.org/content/repositories/
google-snapshots/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.sitebricks</groupId>
            <artifactId>sitebricks</artifactId>
            <version>0.8-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.2.2.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Этот файл pom содержит несколько изменений по сравнению с первоначальной версией, созданной в листинге 1.

  • Мы добавили репозиторий http://oss.sonatype.org/content/repositories/google-snapshots/, где можно найти артефакты Maven для Sitebricks и Guice.
  • В разделе зависимостей мы добавили две зависимости:
    • зависимость от Sitebricks, которая будет включаться во все JAR-файлы Sitebricks, необходимые для проекта;
    • зависимость от базы данных Apache Derby, которая используется в этом проекте. Derby - это встроенная база данных, входящая в Java 6. Главное, что дает эта зависимость ― встроенный драйвер JDBC, необходимый Derby.

Ниже показан файл pom проекта Web-приложения.

Листинг 4. Файл pom.xml Web-приложения

<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>org.developerworks.reviewr</groupId>
  <artifactId>reviewrWeb</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>reviewrWeb Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
        <groupId>org.developerworks.reviewr</groupId>
        <artifactId>reviewrMain</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>reviewrWeb</finalName>
    <plugins>
        <plugin>
             <groupId>org.mortbay.jetty</groupId>
             <artifactId>maven-jetty-plugin</artifactId>
        </plugin>
    </plugins>
  </build>
</project>

В листинге 4 внесены два небольших изменения. Добавлена зависимость от основного проекта, которая сделает код, который мы пишем, зависимым от основного проекта, а также от всех зависимостей основного проекта (в том числе от Sitebricks). Кроме того, добавлен плагин Jetty, который позволяет запустить встроенный Web-сервер Jetty и выполнить на нем приложение. Теперь, когда проекты созданы, можно приступить к использованию Sitebricks.

Настройка Sitebricks с помощью Guice

Одно из преимуществ использования Sitebricks заключается в том, что он требует минимального количества настроек. Во-первых, нужно изменить файл web.xml приложения, как показано в листинге 5.

Листинг 5. web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Reviewr</display-name>
  <filter>
      <filter-name>webFilter</filter-name>
      <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
  </filter>

  <filter-mapping>
      <filter-name>webFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
      <listener-class>org.developerworks.reviewr.AppInjector</listener-class>
  </listener>
</web-app>

Приведенный выше код создает сервлет фильтра, который будет перехватывать входящие запросы HTTP. Вместо того чтобы создать свой собственный фильтр, мы используем GuiceFilter в составе Guice. Для фильтра указываем /* (все запросы направляются на этот фильтр).

В листинге 5 устанавливается также перехватчик контекста сервлета. Он вызывается при запуске Web-приложения. Это делается для настройки Sitebricks при запуске приложения. Напишем специальный класс AppInjector, как показано в листинге 6.

Листинг 6. Настройка Sitebricks с помощью AppInjector

public class AppInjector extends GuiceServletContextListener {

    @Override
    public Injector getInjector() {
        Module module = new SitebricksModule() {
            @Override
            protected void configureSitebricks() {
                scan(ShowRestaurants.class.getPackage());
                bind(RestaurantDao.class).to(RestaurantEmbeddedJdbcDao.class);
                bind(ReviewDao.class).to(ReviewEmbeddedJdbcDao.class);
                bind(String.class)
                        .annotatedWith(Names.named("connStr"))
                        .toInstance("jdbc:derby:reviewrDb;create=true");
                bind(DbManager.class).to(EmbeddedDbManager.class);
            }
        };
        
        Injector injector = Guice.createInjector(module);
        return injector;
}

Приведенный выше код должен показаться знакомым тем, кто знаком с Guice. Он создает модуль Guice. Обычно в Guice реализуют метод configure, но в данном случае используется специальный подкласс Sitebricks Module с реализацией его метода configureSitebricks. Здесь-то и производится вся типовая настройка Guice: связывание интерфейсов для их реализации и настройка свойств приложения.

В примере применяется API scan, уникальный для Sitebricks. Он принимает пакет Java и добавляет его содержимое в классы, управляемые Sitebricks. Мы рассмотрим его использование ниже.

Это все, что требуется для настройки приложения. Большая часть этих настроек на самом деле относится к конкретному приложению, например, все привязки вызовов AppInjector. Они не обязательны, но позволяют использовать Guice для упрощения написания бизнес-логики. Если нужен только Sitebricks, достаточно web.xml и вызова scan. Теперь, когда настройка завершена, можно написать логику приложения.

Отображение результатов

На первой странице приложения будут показаны все рестораны, имеющиеся в системе, и пользователи смогут фильтровать список ресторанов по блюдам, которые в них подают. Sitebricks ― это среда в стиле модель-представление-управление(model-view-control - MVC), но в данном приложении мы сосредоточимся на контроллерах и представлении. Контроллеры ― это простые классы Java. Контроллер для отображения всех ресторанов показан в листинге 7.

Листинг 7. Контроллер ShowRestaurants

@At("/")
public class ShowRestaurants {
    private List<Restaurant> restaurants;
    private String category;
    private LinkedHashSet<String> categories;
    private final RestaurantDao dao;

    @Inject
    public ShowRestaurants(RestaurantDao dao){
        this.dao = dao;
    }
    
    @Get
    public void get(){
        this.restaurants = dao.findAll();
        categories = new LinkedHashSet<String>(restaurants.size());
        for (Restaurant restaurant : restaurants){
            categories.add(restaurant.getCategory());
        }
        if (category != null && category.trim().length() > 0){
            List<Restaurant> filtered = new ArrayList<Restaurant>
(restaurants.size());
            for (Restaurant restaurant : restaurants){
                if (restaurant.getCategory().equalsIgnoreCase(category)){
                    filtered.add(restaurant);
                }
            }
            restaurants = filtered;
        }
    }
    // геттеры и сеттеры опущены для краткости
}


Обратите внимание, что этот класс снабжен аннотацией @At, которая представляет собой аннотацию Sitebricks. Значение "/" указывает Sitebricks на то, что любые входящие запросы для "/" нужно отображать на этот класс. Он будет служить контроллером "домашней страницы" приложения.

Sitebricks точно следует соглашениям HTTP и REST, так что можно использовать разные методы для разных HTTP-методов, таких как GET и POST. Аннотация @Get указывает, какие методы использовать для запросов GET. Здесь можно указать любой метод; никакой связи с "get". Аннотация определяет, какой метод будет вызван.

Указанные выше класс имеет несколько членов-переменных. RestaurantDao - это объект, который используется для получения данных, необходимых странице. Аннотация @Inject конструктора для ShowRestaurants указывает Guice, что нужно внедрить RestaurantDao Другие члены-переменные,  restaurants ,  categories  и  category , образуют модель данных страницы. Переменные  restaurants  и  categories  используются в представлении.

Переменная  variable  на самом деле служит параметром запроса. Sitebricks автоматически связывает с ней переменную запроса с тем же именем. Например, если запрос относится к http://<app>?category=Thai, то категория будет равна Thai. В нашем случае, если категория задана, то она используется для фильтрации отображаемого списка ресторанов.

В листинге 8 показан код представления, использующий модель данных, построенную контроллером.

Листинг 8. Представление ShowRestaurants

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html lang="en">
  <head>
    <title>Reviewr</title>
  </head>
  <body>
      <h1>All Restaurants</h1>
      <form method="get">
          <label for="category">Select category:</label>
          <select name="category" id="category">
              <option value="" label="Any"/>
              @Repeat(items=categories, var="category")
              <option>${category}</option>
          </select>
          <input type="submit" value="Filter"/>
      </form>
      <table class=borderall>
          <thead>
              <tr>
                  <td>Name</td>
                  <td>Category</td>
                  <td>Average Rating</td>
              </tr>
          </thead>
          <tbody>
              @Repeat(items=restaurants, var="restaurant")
              <tr><td><a 
href="/restaurant/${restaurant.name}">${restaurant.name}</a></td>
<td>${restaurant.category}</td><td>${restaurant.averageRating}
</td></tr>
          </tbody>
      </table>
      <div class="msg">Not in the list?
          <a href="/restaurants/new">Add a restaurant!</a>
      </div>
  </body>
</html>

Имя ShowRestaurants.html, указанное выше, совпадает с именем контроллера. Это соглашение используется Sitebricks, так что его не надо задавать через настройки. HTML ― это в основном чистый HTML; без скриптлетов (то есть без JSP). Виджет Sitebricks @Repeat используется для перебора элементов коллекции. Для оценки виджетов он использует язык выражений MVEL. MVEL - это расширение типичного языка выражений JSP/JSF. Код создает таблицу ресторанов, где название каждого ресторана также является гиперссылкой на /restaurant/${restaurant.name}. Например, для ресторана TCBY ссылка будет на /restaurant/TCBY. Подобные динамические URL ― основа Sitebricks. В листинге 9 показано, как они работают с контроллером, который обрабатывает данный пример.

Листинг 9. Контроллер RestaurantDetails

@At("/restaurant/:name")
public class RestaurantDetails {
    private final RestaurantDao dao;
    private final ReviewDao reviewDao;
    private final Logger logger;
    private Restaurant restaurant;
    private String text;
    private String author;
    private Integer rating;
    private Integer restaurantId;

    @Inject
    public RestaurantDetails(RestaurantDao dao, ReviewDao reviewDao, Logger logger){
        this.dao = dao;
        this.reviewDao = reviewDao;
        this.logger = logger;
    }

    @Get
    public void get(@Named("name") String name){
        try {
            name = URLDecoder.decode(name, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
        this.restaurant = dao.findByName(name);
        reviewDao.getReviewsForRestaurant(restaurant);
    }

    @Post
    public String addReview(@Named("name") String name){
        try {
            name = URLDecoder.decode(name, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            logger.log(Level.SEVERE, null, ex);
        }
        restaurant = dao.findByName(name);
        reviewDao.create(restaurant, text, author, rating);
        return "/reviewrWeb/restaurant/"+restaurant.getName();
    }
    
    public boolean getNoReviews() {
        return this.restaurant.getReviews().size() == 0;
    } 
    // геттеры и сеттеры опущены для краткости
}

Опять же, обратите внимание на аннотацию @At. На этот раз ее значение - "/restaurant/:name":name используется, чтобы сообщить Sitebricks, что это динамическая переменная. URL будет соответствовать указанному правилу, и последнюю часть URL будет помещена в переменную с именем  name . Это переменная с нормальным для Guice именем.

Метод get имеет входной параметр с аннотацией @Named("name"). Поэтому Guice внедряет значение, извлеченное из URL, в эту переменную при вызове метода get (который вызывается для запросов GET в силу аннотации @Get).

Пример выполняет декодирование URL переменной, поскольку она входит в состав URL, а не как параметр HTTP-запроса, где декодирование уже выполнено. Иначе Elephant Bar представлялся бы как Elephant%20Bar. Вы могли заметить, что в этом классе есть также метод addReview с аннотацией @Post.

Передача формы

Обработка форм может оказаться одной из наиболее трудоемких задач при разработке Web-приложений. Как и следовало ожидать, Sitebricks блистает и в этой области. В листинге 9 показан контроллер страницы детальных сведений о ресторане. Код представления показан в листинге 10.

Листинг 10. Сведения о ресторане

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html lang="en">
  <head>
    <title></title>
  </head>
  <body>
      <h1>${restaurant.name}</h1>
      <h2>Category: ${restaurant.category}</h2>
      <h2>Average Rating: ${restaurant.averageRating}</h2>
      <h2>Reviews</h2>

      @ShowIf(noReviews)
      <p>This restaurant has no reviews yet.</p>

      @Repeat(items=restaurant.reviews, var="review")
      <div class="review">${review.author}:${review.rating}<br/>${review.text}</div>

      <form method="post">
          <label for="author">Your name:</label>
          <input type="text" id="author" name="author"/>
          <label for="rating">Your rating:</label>
          <select name="rating">
              <option value="0" label="0"/>
              <option value="1" label="1"/>
              <option value="2" label="2"/>
              <option value="3" label="3"/>
              <option value="4" label="4"/>
              <option value="5" label="5"/>
          </select><br/>
          <label for="text">Write your review:</label><br/>
          <textarea id="text" name="text" cols="60" rows="40"/><br/>
          <input type="hidden" name="restaurantId" value="${restaurant.id}"/>
          <input type="submit" value="Submit your review"/>
      </form>
  </body>
</html>

Следуя соглашению об именах, этот файл называется RestaurantDetails.html. В начале файла есть HTML-код для отображения информации о ресторане и всех отзывов о нем. Для этого используется @ShowIf, другой важный виджет Sitebricks. Параметр для этого виджета - логическая переменная, которая в данном случае называется noReviews. Еще влистинге 9 переменной с таким именем не было, но был метод getNoReviews. Он соответствует соглашению об именах JavaBeans и вызывается после анализа виджета @ShowIf.

Более интересная часть HTML-шаблона - это форма в его нижней части. В ней используется метод post, как и должно быть в любой форме, которая меняет сервер (в данном случае, добавляя обзор в базу данных). Она возвращает данные себе же, так что будет использоваться тот же контроллер. В листинге 9 видно, что существует другой метод, addReview с аннотацией @Post. Это метод, который вызывается при передаче формы. Здесь используется тот же шаблон имен значений, что и для метода get.

Взгляните на каждый из элементов формы и на их имена. Эти элементы совпадают с переменными-членами классаRestaurantDetails. Sitebricks автоматически связывает данные формы с членами-переменными, как в случае параметров запроса. Это значительно облегчает задачу разработчика. Метод addReview, который в Sitebricks является методом переадресации, возвращает строку. Он просто возвращает строку с относительным URL переадресации. В данном случае это тот же URL сведений о ресторане, так что будет перерисована страница с подробностями. Его можно легко заменить на URL главной или любой другой страницы.

Заключение

В этой статье говорится о том, насколько Google Sitebricks удобен для разработки Web-приложений Java. Мы рассмотрели все необходимое: создание проекта, использующего Sitebricks, настройку Sitebricks, использование его виджетов и отображение адресов URL. В статье рассмотрены также некоторые другие удобные функции, такие как динамические URL с именованными переменными и связывание форм.

Sitebricks - это компактная среда разработки с универсальными инструментами для быстрого создания Web-приложений. Он распространяет на Web философию Guice. Лучше всего, что Sitebricks ― еще молодая среда. Следите за новыми функциями и экосистемой, складывающейся вокруг Sitebricks.



 Распечатать »
 Правила публикации »
  Обсудить материал в конференции IBM Rational/Telelogic - системный инжиниринг, управление требованиями, изменениями, жизненным циклом ИС, умное управление проектами »
Написать редактору 
 Рекомендовать » Дата публикации: 07.09.2011 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Rational ClearCase Multisite Floating User License
IBM RATIONAL Quality Manager Quality Professional Authorized User Single Install License + Sw Subscription & Support 12 Months
IBM RATIONAL Clearcase Floating User License + Sw Subscription & Support 12 Months
IBM RATIONAL Clearcase Floating User From Rational Clearcase Lt Floating User Trade Up License + Sw Subscription & Support 12 Months
IBM Rational Method Composer Authorized User License
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Компьютерный дизайн - Все графические редакторы
СУБД Oracle "с нуля"
Утиль - лучший бесплатный софт для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Написание программ для микроконтроллеров AVR, PIC, ARM, STM32 (9)
Напишу любую программу на любом искусственном языке. Профессиональный программист. Основная...
 
Разработка устройств на микроконтроллерах (29)
Профессиональный программист. Основная специализация: МИКРОКОНТРОЛЛЕРЫ, АССЕМБЛЕР для любых...
 
Пишу программы на заказ профессионально (3126)
Пишу программы на заказ на языках Pascal (численные методы, списки, деревья, прерывания) под...
 
Ищу программиста для написания программы (40)
Ищу программиста ,владеющего Вижуал Бэйсик и программированием в Экселе, для написания...
 
Разработка программ базы данных (25)
Написание прикладных компьютерных программ (базы данных) на заказ. Разработка корпоративных...
 
 
 



    
rambler's top100 Rambler's Top100