谷歌扩展程序web前端_使用Google Sitebricks构建更好的Web应用程序

Sitebricks(仍处于测试阶段)是一个新的Java™Web应用程序框架。 您可能会想,“为什么还需要另一个Web框架?” 使用Google Sitebricks,您可以快速构建可以由其他人维护或使用的Web应用程序。 Sitebricks建立在Guice之上。 它将Guice的许多原理扩展和扩展到了Web。 与Guice一样,它积极使用批注将配置保留为代码的一部分。 您无需创建或编辑大量XML文件即可使用Guice。 相反,Sitebricks允许您在编写更少代码的同时创建Web应用程序。 您编写的代码将很简单。 您可以查看Sitebricks代码并快速了解发生了什么。 Sitebricks不会损害类型安全性或性能。

在本文中,通过创建示例Web应用程序来了解Sitebricks的功能。 名为Reviewr的示例应用程序将允许用户读取和撰写餐厅评论。 您将使用数据库来保留应用程序中使用的数据(但不会在此上花费太多时间)。 该示例重点介绍利用Sitebricks功能的应用程序部分。

从本文底部的表中下载 Reviewer应用程序示例代码。

先决条件

  • 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.使用Maven创建一个Java Web应用程序
$ mvn archetype:create -DgroupId=org.developerworks.reviewr -
DartifactId=reviewrWeb -DarchetypeArtifactId=maven-archetype-webapp
[INFO] Scanning for projects...

这与清单1相似,但是这次您提供了maven-archetype-webapp的原型ID。 它是Maven的核心原型,它创建了一个基本的Java Web应用程序项目。 现在,您已经创建了项目,打开它们的pom文件以向其中添加Sitebricks。 首先对main业务逻辑项目执行此操作,如清单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>

清单1生成的原始文件开始,已对pom文件进行了多种修改。

  • 您已经添加了一个存储库http://oss.sonatype.org/content/repositories/google-snapshots/ ,您可以在其中找到Sitebricks和Guice的Maven工件。
  • 在“依赖项”部分中,添加了两个依赖项:
    • Sitebricks的依赖项,它将引入项目所需的所有Sitebricks JAR。
    • 对Apache Derby的依赖,Apache Derby是您将在本项目中使用的数据库。 Derby是Java 6的一部分的嵌入式数据库。从此依赖项获得的主要内容是Derby所需的嵌入式JDBC驱动程序。

Web应用程序项目的pom文件如下所示。

清单4. Web应用程序的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>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插件,该插件可以启动嵌入式Jetty Web服务器并在其上运行应用程序。 现在已经设置了项目,您可以开始使用Sitebricks。

使用Guice配置Sitebricks

使用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>

上面的代码创建了一个Servlet过滤器,该过滤器将拦截传入的HTTP请求。 您不是使用自己的过滤器,而是使用Guice随附的GuiceFilter。 您正在映射过滤器/* (将所有请求发送到该过滤器)。

清单5还设置了一个Servlet上下文侦听器。 这是启动Web应用程序时将调用的侦听器。 这里的基本原理是在应用程序启动时配置Sitebricks。 因此,您将编写一个名为AppInjector的自定义类,如下所示。

清单6.使用AppInjector Sitebricks配置
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配置:将接口绑定到其实现并配置应用程序属性。

该示例使用scan ,这是Sitebricks独有的API。 它采用Java程序包,并将其内容添加到Sitebricks管理的类中。 稍后您将看到如何使用它。

您已经完成了应用程序所需的所有配置。 此配置的大多数实际上是特定于应用程序的,例如所有在AppInjector进行的绑定调用。 它们不是必需的,但已完成,因此您可以使用Guice简化编写业务逻辑的过程。 如果只需要Sitebricks,则只需要web.xml和scan调用。 现在配置已完成,您可以编写一些应用程序逻辑。

显示结果

应用程序的第一页将显示系统中的所有餐厅,并使用户可以根据餐厅提供的食物种类来过滤餐厅列表。 Sitebricks是模型-视图-控件(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;
        }
    }
    // getters and setters omitted for brevity
}

请注意,此类由@At注释,这是一个Sitebricks注释。 该"/"值告诉Sitebricks任何传入请求映射为"/"这一类。 该类将充当应用程序“主页”的控制器。

Sitebricks严格遵循HTTP和REST约定,因此允许将不同的方法用于不同的HTTP方法,例如GET和POST。 @Get批注指示用于GET请求的方法。 您可以根据需要命名方法。 “获取”没有什么特别的。 注释决定了将调用哪种方法。

上面的类有几个成员变量。 RestaurantDao是用于检索页面所需数据的对象。 ShowRestaurants的构造函数上的@Inject注释告诉Guice注入RestaurantDao 。 其他成员变量, 餐厅 , 类别和类别 ,形成页的数据模型。 在视图中使用变量restaurant和category 。

类别变量实际上是一个请求参数。 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 border="1">
          <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;
    } 
    // getters and setters omitted for brevity    
}

再次注意@At注释。 这次,它的值为"/restaurant/:name":name用于告诉Sitebricks这是一个动态变量。 它将使URL与此模式匹配,并将URL的最后部分放在一个名为name的变量中。 这是Guice中一个普通的命名变量。

get方法的输入参数已使用@Named("name")注释。 这将导致Guice在调用get方法时将从URL提取的值注入此变量(该方法将被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相同,因此将重新显示详细信息页面。 您可以轻松地将其更改为主页URL或任何其他所需的URL。

摘要

在本文中,您了解了使用Google Sitebricks开发Java Web应用程序有多方便。 您探索了所有基本要素:创建一个使用Sitebricks的项目,配置Sitebricks,使用其小部件以及映射URL。 本文还介绍了其他一些方便的功能,例如带有命名变量和表单绑定的动态URL。

Sitebricks是一个轻量级的框架,提供了用于快速创建Web应用程序的通用工具。 它将Guice理念扩展到了网络。 最棒的是,Sitebricks仍然是一个年轻的框架。 您需要密切关注即将发布的功能以及围绕Sitebricks开发的生态系统。


翻译自: https://www.ibm.com/developerworks/java/library/wa-sitebricks/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值