跳转至内容

使用Click框架进行Java Web应用开发/附录A:常见问题

来自Wikibooks,开放世界中的开放书籍

如何获得帮助?

[编辑 | 编辑源代码]

好的,您已经阅读了文档并查看了示例应用程序,但仍然有一些内容您不理解。您该怎么办?

您可以访问click-user和click-development邮件新闻组。这是您在开源项目中获得支持的地方。它是免费的、友好的,并且通常响应速度很快。这些新闻组是其他人提问的地方,也是用户和开发人员讨论想法的地方。强烈推荐,所以不要害羞。

要注册这些邮件组,请点击以下链接

商业支持方面如何?

[编辑 | 编辑源代码]

如果您需要Click的商业支持或培训,您可以从Avoka Technologies获得。

更多详细信息,请发送邮件至Malcolm Edgar

有哪些开发工具?

[编辑 | 编辑源代码]

推荐的Click开发工具包括

ClickIDE
ClickIDE是由Naoki Takezoe开发的Eclipse Web Tools Project (WTP)插件。
要使用ClickIDE插件,请创建一个“动态Web项目”,然后选择“Click”项目Faclet。

NBClick
Click的NetBeans插件正在由Geertjan Wielenga和Ahmed Mohombe开发。
Velocitywebedit
Velocitywebedit是Eclipse的Velocity和HTML编辑器插件。

安装Velocity Web Edit后,将Eclipe的*.htm文件关联配置为使用Velocity编辑器。通过Eclipse菜单执行此操作:窗口 > 首选项 > 常规 > 文件关联

Veloeclipse
Eclipse的Velocity和HTML编辑器插件
Veloedit
Eclipse的Velocity和HTML编辑器插件

如果Click控件生成所有内容,GUI设计人员如何定义HTML?

[编辑 | 编辑源代码]

在Click中,没有任何东西阻止您手动布局HTML表单。它只是为您提供了自动执行此操作的选项。

您可以使用多种方法生成HTML,每种方法都有其优缺点

使用Click表单和控件为您完成所有HTML渲染。

[编辑 | 编辑源代码]

这是一种80/20方法,您可以快速开发内容,但它可能无法满足您所有的UI样式要求。请注意,表单控件提供了许多[click-api/net/sf/click/control/Form.html#auto-layout 自动布局]选项,请参阅[examples.html click-examples]“表单属性”以进行演示。表单控件还在表单的HTML元素中呈现类属性“form”、“fields”、“errors”和“buttons”,从而可以进行细粒度的CSS控制。

例如,您可以将表单配置为在顶部显示标签,并希望增加字段之间的垂直间距。要执行此操作,只需在表单前面定义CSS样式即可

 <style type="text/css">
    td.fields { padding-top: 0.75em; }
 </style>

 $form

字段还使用“id”属性呈现,从而可以操作各个字段。

子类化Click表单/控件以自定义HTML渲染。

[编辑 | 编辑源代码]

这是一种确保Web应用程序中通用外观的好方法,但您需要亲自动手编写一些代码。

使用Panel类创建可重用的HTML块。

[编辑 | 编辑源代码]

Panel控件支持自定义Velocity模板,这是一种创建可重用HTML部分的理想方法,您可以将其包含在许多页面中。Panel还支持嵌套控件,使您的部分能够支持基于控件的行为。

使用Velocity宏进行通用HTML布局。

[编辑 | 编辑源代码]

这很容易做到,并且可以在您的Web应用程序中实现良好的重用。

手动布局您的HTML表单。

[编辑 | 编辑源代码]

这为您提供了最终的演示控制,但在您的Web应用程序中不提供任何重用。

如何使用相同的HTML模板创建多个页面?

[编辑 | 编辑源代码]

要实现这一点,可以使用页面模板技术,该技术在页面模板主题中进行了详细说明。在您的Web应用程序中强烈建议使用页面模板,因为它提供了许多好处,包括

  • 大大减少了需要维护的HTML数量
  • 确保您的应用程序具有统一的外观和风格
  • 使您的应用程序更健壮,因为需要测试的代码更少

为什么控件监听器方法必须返回布尔值?

[编辑 | 编辑源代码]

控件监听器方法必须返回一个布尔值,以指示是否应该继续处理页面的控件和方法。要继续处理,监听器方法应返回true,要中止则应返回false。您可能希望中止进一步处理的原因是,您可以直接导航到另一个页面,而不是继续执行其他可能很耗时的控件或页面方法。您可以将此功能用作break或goto语句。例如

public boolean onLogoutClick() 
{
   setRedirect(Logout.class);
   return false;
}

能否从表单中排除某些字段?

[编辑 | 编辑源代码]

要排除在共享表单类中显示某些字段,请使用Form.removeFields()方法。

您甚至可以在页面模板中执行此操作。只需确保在$form呈现自身之前调用它即可。例如

$form.removeFields(["field11", "field15", "field22"])

$form

如何国际化页面和控件?

[编辑 | 编辑源代码]

Click为应用程序本地化和国际化(I18N)需求提供了良好的支持。

页面消息

[编辑 | 编辑源代码]

Page类使用[click-api/net/sf/click/Page.html#getMessage(java.lang.String) getMessage(String)]方法支持页面特定的字符串本地化包。例如,一个Login类在类路径上有三个区域设置字符串属性文件

/com/mycorp/pages/Login.properties
/com/mycorp/pages/Login_en.properties
/com/mycorp/pages/Login_fr.properties

在您的Login Page类中,您可以使用getMessage()方法来查找请求本地化的消息字符串。

public void onInit() 
{
    addModel("title", getMessage("title"));
}

在您的HTML页面模板中,您还可以使用MessagesMap对象访问本地化消息,该对象使用名称“messages”添加到模板中。例如

<h2>$messages.title</h2>

您还可以使用控件名称查找约定在页面属性文件中定义Field和ActionLink标签和标题值。

  • ActionLink.getLabel()
  • ActionLink.getTitle()
  • Field.getLabel()
  • Field.getTitle()
  • FieldSet.getLegend()

字段消息

[编辑 | 编辑源代码]

Field控件类共享一个通用的消息属性文件

/click-control.properties

field类提供了一些getMessage(String)方法,这些方法支持本地化字符串和消息格式化。

如何将页面编码为UTF-8字符集?

[编辑 | 编辑源代码]

要将页面编码为UTF-8字符集,您需要创建一个WEB-INF/velocity.properties文件,其中包含以下属性

input.encoding=UTF-8

这将配置Velocity运行时以使用UTF-8。

您还需要将页面标头的内容类型设置为UTF-8。您可以使用headers元素在您的WEB-INF/click.xml文件中为所有应用程序页面全局执行此操作

<click>
 ..
 <headers>
   <header name="Content-Type" value="text/html;charset=UTF-8"/>
 </headers>
 ..
</click>

这将设置页面的HttpServletResponse的“Content-Type”标头为“text/html;charset=UTF-8”。或者,您可以覆盖Page getContentType()方法以使用此内容类型。

如何在应用程序中指定使用的字符集?

[编辑 | 编辑源代码]

您可以在WEB-INF/click.xml:

<click charset="UTF-8">
 ..
</click>

中指定应用程序字符集。此字符集用于Velocity输入编码和响应Content-Type。因此,如果您在WEB-INF/click.xml中指定了字符集,则无需创建WEB-INF/velocity.properties.

如果您想在Velocity模板中使用其他字符集,可以通过WEB-INF/velocity.properties.

如何防止多次提交表单?

[编辑 | 编辑源代码]

您可以使用Post Redirect模式来防止多次提交表单。使用此模式,一旦用户提交了表单,您就会重定向到另一个页面。如果用户随后按下刷新按钮,他们将对当前页面进行GET请求。

要防止用户使用浏览器后退按钮重新提交表单,请使用Form onSubmitCheck()方法

public class Purchase extends Page 
{
    ..

    public boolean onSecurityCheck() 
    {
        return form.onSubmitCheck(this, "/invalid-submit.html");
    }
}

如何使用*.html Click页面?

[编辑 | 编辑源代码]

Click不支持*.html文件作为Click页面。这些文件不会由ClickServlet处理,旨在用作静态内容。

Click和Cayenne应该使用哪些JAR文件?

[编辑 | 编辑源代码]

要使Click和Cayenne能够很好地协同工作,您需要将以下JAR文件包含在您的WEB-INF/lib目录中

  • ashwood-1.1.jar
  • cayenne-nodeps-1.2.x.jar
  • click-1.x.jar
  • click-extras-1.x.jar
  • log4j-1.2.x.jar
  • oro-2.0.8.jar

默认的Cayenne JAR包含Velocity 1.3,它与使用Velocity 1.5-dev的Click不兼容,因此我们使用Cayenne无依赖项JAR。当使用Cayenne nodeps JAR时,我们需要添加一些其他Java库,包括ashwood、log4j和oro。

如何将Click集成到Spring中?

[编辑 | 编辑源代码]

要将Spring与Click集成,请配置SpringClickServlet而不是普通的ClickServlet。SpringClickServlet包含在Extras库中。

但是,Spring MVC框架与Click不兼容。Spring框架使用类似于Struts和WebWork的低级命令模式设计。Spring使用DispatcherServlet将请求路由到Controller对象,然后将ModelAndView结果传递到渲染层。

public interface Controller 
{
   public ModelAndView handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws Exception;
}

在Spring MVC中,集成插件点是Controllers。

Click使用更高级别的设计结构,专注于页面和控件。Click使用自己的ClickServlet来调度对PagesControls的请求,它们是Click的插件点。

Click是否支持JSP?

[编辑 | 编辑源代码]

Click完全支持JSP页面。

JSP页面可以像Velocity模板一样自动加载,也可以在click.xml文件中显式定义。

<page path="customers-table.jsp" class="com.mycorp.pages.CustomersTable"/>

页面的模型数据值会自动作为属性添加到请求中,以便在JSP中使用。

其他作为请求属性添加的Click值包括

  • context - Servlet上下文路径,例如 /mycorp
  • format - 用于格式化对象显示的[click-api/net/sf/click/util/Format.html Format]对象
  • forward - JSP页面资源(.jsp文件)
  • messages - 页面[click-api/net/sf/click/Page.html#getMessage(java.lang.String) getMessage()]方法的[click-api/net/sf/click/util/MessagesMap.html MessagesMap]适配器
  • path - 页面的映射请求[click-api/net/sf/click/Page.html#path path]。请注意,这将具有.htm扩展名而不是.jsp扩展名

Click的性能如何?

[编辑 | 编辑源代码]

Click速度很快。

当Click框架处理请求时,它会创建相对较少的对象。这些对象包括Page、Context、Format和一些Controls,而Controls又包含一些列表、映射和字符串。

现代JVM分配少量/中等数量的短生命周期对象的速度非常快。

Click实际执行的工作量非常少。

TheonProcess()方法遍历Controls列表并执行简单的操作。

ControltoString()方法在渲染表格时可能会分配大型StringBuffer,但表单很少超过4000个字符。当Click创建新的StringBuffer时,它会尝试确定最大可能的尺寸,以避免额外的内存分配和arraycopy操作。

Click几乎没有使用反射。反射仅由Control回调监听器使用。

okButton.setListener(this, "onOkClicked");

处理请求的下一步是渲染响应。Velocity主要负责此步骤。

Velocity也很快。

虽然在这个领域很难获得具体的性能数据,但直到最近,Velocity都被认为比JSP快。然而,Velocity邮件列表上的近期讨论表明,JSP编译器已经改进到JSP比Velocity略有性能优势的程度。无论如何,JSP和Velocity都非常快。

如何对Click页面进行单元测试?

[编辑 | 编辑源代码]

通常建议不要为Click页面编写JUnit风格的自动化单元测试,因为成本效益比非常差。如果Click页面中存在复杂的业务逻辑,则应将此代码重构到一个业务级服务类中,以便可以轻松地对其进行单元测试并在多个地方重用。

如果您仍然需要为Click页面编写单元测试,请使用Click模拟MockContextMockRequest类,这些类位于mock发行版目录中。

为什么Click不使用Commons Logging/Log4J进行日志记录?

[编辑 | 编辑源代码]

Click最初不与Velocity一起使用Log4J,因为与垃圾回收VelocityEngines相关的追加程序关闭内存泄漏。此问题已在最新的Velocity 1.5开发流中解决。

由于IBM WebSphere应用服务器的某些版本上出现的类加载器问题,因此未使用Commons Logging。

为什么Click不使用FreeMarker代替Velocity?

[编辑 | 编辑源代码]

FreeMarker是一个功能强大的模板引擎,它与Velocity一起被评估用于Click。虽然FreeMarker具有许多Velocity不具备的复杂功能,但选择Velocity是因为它更容易学习,并且不使用XML风格的标记语法。

与Velocity相比,FreeMarker的优势之一是错误报告。Click通过使用Velocity 1.5的新增增强错误报告功能解决了此问题。

Click将渲染包含错误的源代码。例如

  • 页面解析错误
  • 空指针错误

为什么开发新的Web应用程序框架?

[编辑 | 编辑源代码]

因为现有的框架无法满足我的需求。Struts的功能不多,而Tapestry过于复杂。有关更全面的答案,请参阅为什么选择Click

华夏公益教科书