已阅读5页,还剩48页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
创建简单的创建简单的 WEBX 应用应用 1 前言前言 阿里巴巴网站所采用的 WEB 应用框架是 Webx 本文将指导你建立一个简单的 Webx 应用 在尝试本文的例子之前 1 请先阅读 新人指南 并按照其指示 在你的电脑上安装适当的软件 2 请再阅读 创建简单的 WEB 应用 并熟悉 Servlet API 中的基本概念 以及创建 布署 调试 WEB 应用的技巧 2 准备准备 创建一个新项目创建一个新项目 为了能进行本文的例子 请用 antx 创建一个新的工程项目 mkdir workshop 2 cd workshop 2 antx gen web 这样 你就会得到一个项目的初始目录 workshop 2 project jelly project xml docs src descriptors web web xml java webroot WEB INF 然后 请修改几个文件 第一个文件是 project xml 这个文件指出了项目的名称 依赖哪些 jar 包等信息 include 第二个要修改的文件是 project jelly 这个文件指出了该项目默认 build 成一个 WAR 包 改完这两个文件以后 就可以生成 eclipse 项目了 请在项目目录下执行 antx eclipse 这样便生成了 classpath 和 project 这两个 eclipse 相关的文件 请打开 Eclipse 并导入这个项目 至此 你就可以在 eclipse 下开发项目了 3 创建第一个创建第一个 Webx 应用应用 3 1 创建 布署 运行 利用 Webx 框架来创建 WEB 应用 是一件比较简单的事情 下面 我们将创建一个在屏幕上显示 Hello World 的 Webx 应用 与其说 创建 不如说 配置 因为显示 Hello World 页面 并不需要写一行程序 3 1 1 创建创建 web xml 首先 请修改 src descriptors web 目录下的 web xml 文件 WebxController com alibaba webx WebxControllerServlet initAllServices true WebxController htm WebxController do 这个 web xml 中定义了一个被称为 Webx controller 的 servlet 并把它映射到 htm 和 do 两个 URL 中 Webx Controller Servlet 的定义中 包含一个 initAllServices 参数 将 initAllServices 设置成 true 会让 webx 在启动时就初始化所 有的 services 以便及早发现初始化异常 3 1 2 创建创建 log4j xml 虽然不是必须的 但是我还是建议你配置一下日志系统 妥善地配置好日志系统 有助于你在将来的开发 调试中发 现错误 请在 src webroot WEB INF 目录下 创建一个 log4j xml 内容如下 这个配置文件有点长 但你完全可以按照你的意愿来自由地修改这个文件 配置的方法请参见 Log4j 的文档 3 1 3 创建创建 webx xml 每个 webx 应用 都需要有一个 webx xml 配置文件 这个文件定义了 Webx 所用到的所有 services 的配置 请在 src webroot WEB INF 目录下创建 webx xml 在这个文件中 目前只配置了一个在这个文件中 目前只配置了一个 Service PipelineService 管道服务 管道服务 PipelineService 是是 Webx 的核心服务 的核心服务 提供了提供了 webx 请求执行的流程 请求执行的流程 3 1 4 创建创建 pipeline xml 接下来 让我们创建 WEB INF pipeline xml 管道配置文件 这个文件的意思过会再解释 让我们先创建一个页面 3 1 5 创建页面模板创建页面模板 请在 src webroot 目录下 创建如下子目录 src webroot templates control layout screen 然后在 templates screen 目录下 创建一个 hello vm 如下 Hello 你好 世界 现在时间 date 3 1 6 布署 运行布署 运行 至此 所有的文件和目录都已经创建好了 我们可以对它打包和发布 请在 workshop 2 目录下执行下列命令 antx antxexpand target workshop webapp 2 war tomcat webapps workshop 其中 tomcat 为你安装 tomcat 的目录 启动 tomcat 打开浏览器看一下效果 这个页面是不是有问题 是的 这里显示的当前时间为 date 先别急 我们会稍后解决这个问题 3 2 审视 Webx 应用的结构 这是一个简单的应用 由于它是基于标准的 JavaEE Web 应用规范 因此它的目录结构也没有什么特殊的地方 workshop 2 templates control layout screen hello vm WEB INF log4j xml pipeline xml web xml webx xml classes lib jar 通常我们会把所有配置文件都放在 WEB INF 目录下 除了标准的 web xml 以外 我们增加了 webx xml pipeline xml 和 log4j xml 等几个文件 随着应用变得复杂 我们后面还会创建少量新的配置文件 通常我们总是把模板放在 templates 目录下 不过只要你喜欢 你完全可以改成其它的目录名 Vm 后缀的为 Velocity 的模板 jsp 后缀的为 JSP 模板 ftl 后缀的为 Freemarker 模板 3 3 Webx 执行的流程 当你在浏览器里敲入 http localhost 8080 workshop hello htm 时 在 Webx 中发生了哪些事呢 很简单 首先 根据 web xml 中的映射 htm 被映射到 Webx Controller Servlet 因此 Webx Controller Servlet 会被激 活来处理这个请求 而 Webx Controller Servlet 只做了一件事 就是 执行执行 pipeline 所谓 pipeline 即管道 它是由一个或多个 阀门 Valve 构成的 我们可以想象 水从管道的一头流入 从管道另一 头流出 其中经过很多个阀门 事实上 阀门可以控制水流的方向 甚至改变水分子的组成结构 这真是一个不寻常的管 道 管道是由 PipelineService 来创建并管理的 在上面的例子中 PipelineService 读取 WEB INF pipeline xml 来创建管道 在请求被处理的过程中 这个管道做了哪些事呢 让我们逐个简介一下 3 3 1 TryCatchFinallyValve 这个阀门类似于 Java 中的 try catch finally 结构 它将整个管道分成了三个分支 try 分支 catch 分支 finally 分支 1 首先 try 分支会被执行 2 在执行过程中 如果发生异常 就会转入到 catch 分支 通常可以在这里做错误处理的工作 3 无论发生异常与否 finally 分支都会被执行 通常可以在这里做一些扫尾工作 3 3 2 SetLoggingContextValve valve valve 这是一个可写可不写的阀门 但是写了它以后 有助于我们在日志中发现错误的根源 下面是我们的 log4j 日志文件中的一行错误信息 2007 01 31 13 36 05 509 workshop hello htm workshop hello htm ERROR screen Error Error occurred while processing the HTTP request 发现了吗 Log4j 把导致错误的请求的 URL 也记录在案了 这是怎么做到的呢 原来 log4j 有一个叫做 MDC 的功能 它利用 ThreadLocal 变量保存当前线程的上下文信息 回看我们的 log4j xml 配置 其中 X requestURIWithQueryString 就是引用了 MDC 中的内容 现在的问题是 MDC 何时被设置 当然是在请求 开始的时候设置 SetLoggingContextValve 做的就是这件事 最后 别忘了 当请求结束时 我们必须在 finally 分支中 用 SetLoggingContextValve 清除 MDC 的内容 MDC 中可以包含哪些内容呢 事实上可以包含任何内容 SetLoggingContextValve 设置了如下内容 X 参数名参数名 说明说明示例示例 method请求的方法GET POST requestURL完整 URL 不含 query stringhttp localhost 8080 workshop hello htm requestURLWithQueryString完整 URL 包含 query stringhttp localhost 8080 workshop hello htm id 1 requestURI不包含 host 信息的 URI 不含 query string workshop hello htm requestURIWithQueryString不包含 host 信息的 URI 包含 query string workshop hello htm id 1 queryStringQuery stringid 1 MSIE 6 0 Windows NT 5 1 referrer用户是从哪个页面点击到该页的http localhost 8080 workshop hello htm 事实上 我们完全可以扩展 SetLoggingContextValve 以实现更多的功能 例如 在日志中显示当前登录的用户名在日志中显示当前登录的用户名 SetLoggingContextValve 使日志信息变得对我们更有意义 3 3 3 SetLocaleValve SetLocaleValve 被用来确定请求的输入 输出字符集编码 地域信息 地域信息 Locale 会影响 ResourceBundle 表单出错提示信息 邮件生成等和 Locale 相关的组件的执行 结果 在上面的配置中 默认将采用 zh CN 即中国大陆 作为当前请求的 Locale 字符集编码 Charset 用来作为输出页面时所用的编码 即 Content Type 中指定的 charset 输出输出字符集编 码 和解析表单或 query string 时所用的编码 即输入输入字符集编码 在上面的配置上 默认使用 GBK 作为字 符集编码 在正常情况下 浏览器会用 Content Type 中指定的 charset 来提交表单 因此输入 输出编码是一致的 然而 有些情 况下 输入 输出编码会不一致 比如 通过外部系统提交的信息 如贸易通 旺旺 合作网站 其字符集编码未必和 网站一致 SetLocaleValve 提供了一种特别的参数 来处理这种特殊情况 SetLocaleValve 的处理逻辑是这样的 1 一般情况下 SetLocaleValve 将根据其配置中的 defaultLocale 和 defaultCharset 来确定当前 locale 和 charset 该 charset 将被用于解析参数和输出页面 2 如果 URL 中包含类似这样的参数 lang zh HK UTF 8 这意味着用户要求进入中国香港版 zh HK 网页 并 使用 UTF 8 作为默认的 charset SetLocaleValve 会把这个值保存在 cookie 或 session 中 这样后继的页面不用指 定 lang 参数 也会使用 zh HK UTF 8 地域和字符集编码 3 如果 URL 中包含参数 lang default 这意味着用户要求回到系统默认的 locale 和 charset 即 valve 参数中所指 定的 defaultLocale 和 defaultCharset 在本例中 分别为 zh CN 和 GBK 4 如果 URL 中包含参数 input charset UTF 8 这意味着必须用 UTF 8 来解码参数 需要注意的是 这个值可能 和 valve 配置中指定的 defaultCharset 不同 SetLocaleValve 将仍然以前面所说的规则来确定页面的输出字符集编 码 外部系统 如贸易通 旺旺 合作网站 通过 HTTP 方式向系统发送请求时 最好指定该参数 而不是假设 网站的默认 charset 这样 当网站的默认 charset 发生改变时 也不会影响到外部系统 3 3 4 AnalyzeURLValve AnalyzeURLValve 用来分析 URL 的成分 有不少初学者误以为 URL 和物理文件之间是一一对应的 例如 http localhost 8080 workshop hello htm 代表 workshop 目录下有一个 hello htm 文件 这是不一定的 事实上 你应该把 URL 看作一个参数 一个 URL 实际对应的操 作是什么 可以由应用程序自己来决定 以 http localhost 8080 workshop hello htm 为例 URL 的分析分为下面几步 1 workshop 被称为 Context Path 应用服务器看到 workshop 就把这个请求交给 workshop 应用来接管 2 hello htm 被称为 Servlet Path 因为我们在 web xml 中把 htm 映射到 Webx Controller Servlet 所以 Webx Controller Servlet 就接管了这个请求 3 Webx Controller Servlet 激活 pipeline 继而调用 AnalyzeURLValve 来分析 hello htm 是什么意思 根据 webx 默认 的映射规则 hello htm 被转换成 hello vm 经过上述转换 最后得到的结果被称为 target 在这个例子中 target 的值为 hello vm 有人想当然认为 hello vm 是代表 Velocity 模板 事实上 这也是不一定的 到目前为止 只能称它为 target 在后 续的 valve 中 我们会将 hello vm 解释为解释为 Velocity 模板 3 3 5 ChooseValve ChooseValve 用来作条件分支 当中的条件被满足时 这个 when 所包含的分支就被执行 如果所有 when 都不满足 就执行 otherwise 分支 标签支持多种条件 1 如果 target 的后缀为 jsp 或 vm 那么就执行该分支 2 如果 target 的值以 images 开头 那么就执行分支 3 如果 path 的值以 member images 开头 那么就执行分支 和 target 不同 path 是 URL 去掉 contextPath 之后的剩 余部分 而 target 是由 AnalyseURLValve 翻译而来的 在我们的例子中 hello vm 匹配了分支 在这个分支里 hello vm 被视作 screen 模板 并作进一步处理 3 3 6 PerformActionValve PerformActionValve 用来执行 action 参数 actionParam 的值指明了 valve 将根据什么参数来确定 action 的名称 例如 假如 URL 为 http localhost 8080 workshop hello htm action myAction 那么 valve 将会执行 MyAction 类 有关 action 的细节 我们将在后面展现 3 3 7 PerformScreenTemplateValve PerformScreenTemplateValve 用来执行 screen 和模板 假如 target 的值为 xxx yyy hello vm 那么 valve 会 1 在 templates screen 目录下 找到 xxx yyy hello vm 模板 2 依次查找 screen 类 a xxx yyy Hello 如果找不到 尝试下一个 b xxx yyy Default 如果找不到 尝试下一个 c xxx Default 如果找不到 尝试下一个 d Default 如果找不到 尝试下一个 e TemplateScreen 系统默认 screen 不可能找不到的 3 执行 screen 并渲染 screen 模板 4 如果存在 layout 布局 则渲染 layout 并将 screen 放于布局中 关于 layout 布局 后面会讲到 3 3 8 PerformScreenValve 和前一个 valve 不同 PerformScreenValve 不关心模板 只关心 screen 类 假如 target 的值为 xxx yyy hello do 那么 valve 会 1 查找 screen 类 xxx yyy Hello 2 执行 screen 类 3 如果存在 layout 布局 则渲染 layout 并将 screen 放于布局中 3 3 9 RedirectTargetValve RedirectTargetValve 实现了内部重定向 如果在 screen action 里调用了 rundata setRedirectTarget 那么 RedirectTargetValve 会将控制转向到标记了 label 的 valve 上 从而实现内部的循环 在上面的例子中 PerformActionValve 和 PerformScreenTemplateValve 或 PerformScreenValve 被重新执行了 但 target 的值因 setRedirectTarget 而改变 因而实现了内部重定向 3 3 10 SetErrorPageValve SetErrorPageValve 的工作是显示错误页面 error vm 4 增加布局增加布局 在实际的应用中 一组相关的页面会有类似的布局 而布局往往和页面所要表现的业务逻辑显得无关 例如显示菜单 标题 版权等信息 现在 我们在前面的例子中 增加 布局 的功能 LayoutLayoutLayout ControlControlControl ControlControlControl ControlControlControl ScreenScreenScreen 标题 标题 标题 LogoLogoLogo 版权信息版权信息版权信息 导航栏 菜导航栏 菜导航栏 菜 单单单 页面主体页面主体页面主体 4 1 创建布局 为了创建类似图中所示的布局 我们需要在 templates layout 目录下创建一个 default vm Hello control control setTemplate setTemplate header vm header vm control control setTemplate setTemplate menu vm menu vm screen placeholder screen placeholder control control setTemplate setTemplate bottom vm bottom vm 在这个布局中 我们看到有两种特别的标记 1 screen placeholder 这个标记将被 screen 的内容所取代 在本例中 即 templates screen hello vm 的内容 2 control setTemplate 这个标记将被 control 的内容所取代 Control 是一种可重用的页面片段 它的 模板在 templates control 目录下 4 2 创建 control 模板 在这个 layout 中 我们引用了三个 control header vm menu vm 和 bottom vm 我们需要在 templates control 目录下创 建这三个文件 内容分别如下 header vm 标题 Logo menu vm 菜单 菜单 菜单 菜单 菜单 bottom vm 版权信息 4 3 修改 screen 模板 使用 layout 以后 screen 模板不再充当显示完整页面的角色 而是只显示和业务相关的部分页面 因此 我们需要稍 微修改一下 screen 模板 去掉其内容中头尾的部分 因为这部分内容 已经写在 layout 模板中了 Hello 你好 世界 现在时间 date 重新启动应用服务器 现在 你应该看到一个完全不同的页面了 4 4 查找布局的规则 刚才我们创建了 default vm 布局 需要强调的是 这个布局不仅仅对 hello vm 有效 而且对所有页面都有效 不信的 话 你可以在 templates screen 目录下创建一个新的 screen 试试看 不需要重启机器 你就可以看到效果 所有的页面现在 都被 框 在这个布局里面了 假如我的大部分页面的布局是相同的 但是有一两个页面例外 我该怎么做呢 有办法 Webx 的布局规则很灵活 足够应付大部分的场景 假如我的 screen 模板名为 xxx yyy hello vm 那么 Webx 将依次查找下面的 layout 模板 1 xxx yyy hello vm 如果找不到 尝试下一个 2 xxx yyy default vm 如果找不到 尝试下一个 3 xxx default vm 如果找不到 尝试下一个 4 default vm 如果找不到 尝试下一个 5 如果上面所有都找不到 就显示不带 layout 的 screen 如果你希望对 hello vm 指定 layout 你可以在 templates layout 目录下 为其特别创建一个和 screen 同名的 layout 模板 就可以了 Webx 假设同一目录下的模板 在功能上是相关的 因此布局也是相似的 因此你不仅可以在 layout 根目录下 设置 default vm 也可以在各级子目录下设置 default vm 4 5 指定页面标题 细心的你也许已经注意到了 采用 layout 的机制以后 页面的 title 是由 layout 来控制的 而不是由 screen 来控制的 因为 screen 的模板中已经不包含标签了 但这样是不合逻辑的 因为不同的 screen 可 能会有不同的标题 除了标题 还有 Java Script CSS 等很多内容 都应该由 screen 来控制 怎么解决这个矛盾呢 Webx 提供了一个 HtmlPageAttributeTool 工具类来解决这个问题 class HtmlPageAttributeTool addBodyAttribute String String addScript String addStyle String addStyleSheet String addStyleSheet String String String String setAlinkColor String setBackground String setBgColor String setDescription String setHttpEquiv String String setKeywords String setLinkColor String setTextColor String setTitle String setVlinkColor String getBodyAttributes getDefaultDoctype getHttpEquivs getMetaTags getScripts getStyles getStyleSheets getTitle 你可以用 page 这个特殊的变量来引用这个对象 并调用其方法修改页面 title 甚至页面颜色 CSS JavaScript 等全 局页面属性 让我们修改一下 templates screen hello vm page page setTitle setTitle 新标题 新标题 你好 世界 现在时间 date 注意 在 page 中所设置的属性并不会自动出现在页面中 我们还需要修改一下 layout 模板做配合 修改后的 templates layout default vm 模板如下 showHead showHead Hello Hello 在这个 layout 模板中 我们使用了两个 Velocity 宏 showHead 和 bodyAttributes 显然 我们需要在 Velocity 中定义 这些宏 为此 我们还需要创建一个文件 templates macros vm 内容如下 显示所有 headers macro showHead defaultTitle showTitle defaultTitle showMetaTags showHttpEquiv showStylesheets showJavascripts end 显示标题 如果未提供标题 则使用默认值 macro showTitle defaultTitle if page title page title else defaultTitle end end 显示 meta tags macro showMetaTags foreach metaTag in page metaTags keySet end end 显示 meta http equiv macro showHttpEquiv foreach httpEquiv in page httpEquivs keySet end end 显示 stylesheets macro showStylesheets foreach styleSheet in page styleSheets end end 显示 javascripts macro showJavascripts foreach script in page scripts end end 显示 body attributes macro bodyAttributes foreach attributeName in page bodyAttributes keySet attributeName page bodyAttributes get attributeName end end 最后 我们需要修改一下 webx xml 在 VelocityService 中装载这个宏文件 property 虽然创建 Velocity 宏的步骤略显复杂 但是这样的工作在每个项目中只需要做一次就可以了 重启应用服务器 你就会看到新的页面标题 5 页面驱动页面驱动 到目前为止 我们已经创建了相当复杂的页面 但我们却没有为此写一行程序 而且在创建页面的过程中 大部分修 改都能立即生效 而不需要重启服务器 这种接近于所见即所得的方式 非常贴近一个真实网站的开发流程 在真实 的网站项目中 产品设计师首先设计的内容就是页面 确定页面的数量 功能 布局 与此同时 美术设计师会配合 产品设计师对页面做美化 直到最后 Java 工程师才会介入 开始编写程序 和其它大多数的 Web 框架不同 Webx 是以页面为驱动的 它允许你先把页面做出来 在必要时才让 Java 工程师 介入 最重要的是 产品设计师制作页面时 基本上不需要 Java 工程师的介入 他们只需要了解一些书写模板和 HTML 的技巧 以及前面所讲的页面布局的知识就可以了 和普通 HTML 页面不同的是 Webx 页面是真正的动态页面动态页面 在前面的 Velocity 模板中 我们已经使用了好几个变量 control page 事实上 还有更多现成的变量可用 它们都是预设在系统内部的常用工具 而且我们还可以创建新的工 具 下面是在页面中可用的工具 工具名工具名类名类名作用域作用域说明说明 arrayUtilArrayUtil全局 classLoaderUtilClassLoaderUtil全局 classUtilClassUtil全局 enumUtilEnumUtil全局 exceptionUtilExceptionUtil全局 fileUtilFileUtil全局 静态工具类 参见相应类的 API 文档 其中最常用的当属 stringUtil 和 stringEscapeUtil 例如 判断字符串为空串 if stringUtil isEmpty var stringUtil isEmpty var end 进行 HTML 编码 localeUtilLocaleUtil全局 mathUtilMathUtil全局 messageUtilMessageUtil全局 objectUtilObjectUtil全局 streamUtilStreamUtil全局 stringEscapeUtilStringEscapeUtil全局 stringUtilStringUtil全局 systemUtilSystemUtil全局 进行 JavaScript 编码 var myvar stringEscapeUtil escapeJavaScript var stringEscapeUtil escapeJavaScript var controlControlToolRequest创建 control 例如 control setTemplate header vm control setModule myControl formFormToolRequest处理表单 后文会讲到 pageHtmlPageAttributeToolRequest设置页面属性 rundataRunDataRequest取得 request response 相关的数据 例如 rundata parameters id 取得 id 123 参数的值 uriURIBrokerToolRequest生成 URL 后文会讲到 所谓全局作用域 意思是这种工具仅当系统启动时被初始化 随后被所有页面重复使用 这种工具必须是无状态的 和全局作用域相对的 是 Request 作用域 这种作用域的工具会在每次请求时创建和初始化 因此可以在它里面保存与当 前请求相关的数据 但这种工具不能被多个请求共享 如果我所需要的功能不在上面的列表中 怎么办呢 没关系 你可以创建你自己的工具 在创建这个工具之间 先问自己一个问题 这个工具中是否包含仅和当前 request 相关的数据 如果是 那么它是一个 Request 作用域的工具 否则 它是一个全局作用域的工具 你需要修改 webx xml 以增加新的工具 property 在这个配置中 我们指定了一个 request 作用域的新对象 java util Date 之所以设置成 request 而不是 global 作用域 是因为我们希望每次请求 对象都被更新 重启服务器 我们就可以看到页面中显示出了当前的时间 6 验证表单验证表单 现在 让我们做一个新的功能 注册用户 每个用户需要填写下面的内容 以成为我们的会员 字段名描述限定 ID唯一用户 ID必填项 由字母 数字 下划线构成 最少 4 个字符 最多不超过 10 个字符 Password用户验证密码必填项 由字母 数字 下划线构成 最少 4 个字符 最多不超过 10 个字符 为了安全 密码不得与 ID 相同 Password Confirm 密码必须填两遍 以防输错必填项 必须和 Password 相同 Name用户名必填项 可由任何字符构成 包括中文 不超过 20 个字符 Email电子邮件地址可选项 必须符合电子邮件地址的规范 Description个人描述 心情故事可选项 在 Webx 中做这样的表单验证相当简单 不需要写一行程序 6 1 创建 form xml 首先 你需要在 WEB INF 目录下创建一个新的文件 form xml 内容如下 必须填写 displayName displayName 必须由字母 数字 下划线构成 displayName 最少必须由 minLength 个字组成 最多不能超过 maxLength 个字 必须填写 displayName displayName 必须由字母 数字 下划线构成 displayName 最少必须由 minLength 个字组成 最多不能超过 maxLength 个字 displayName 不能与 id displayName 相同 必须填写 displayName displayName 必须和 password displayName 相同 必须填写 displayName displayName 最多不能超过 maxLength 个字 displayName 必须是合法的 E mail 地址 这个文件定义了用户要填写的表单的信息 它包括如下内容 1 文件以标签开始 2 由一个或多个组成 每个 group 代表一组要验证的字段 每个 group 有一个唯一的名字 3 由一个或多个组成 每个 field 代表一个要验证的字段 每个 field 有一个在 group 范围内唯一的名 字 4 由零个或多个组成 每个 validator 代表一个验证条件 如果条件不满足 validator 中的 message 信息将被显示出来 6 2 修改 webx xml 为了使用刚刚创建的 form xml 我们需要修改一下 webx xml 文件 WEB INF form xml WEB INF form xml 6 3 创建 register vm 模板 最后 我们来写 screen 模板 register vm 在 templates screen 目录下创建这个文件 macro registerMessage field if field valid field message end end set group form register defaultInstance 用户注册 用户 ID registerMessage group id 密码 registerMessage group password 再输一遍密码 registerMessage group passwordConfirm 用户名 registerMessage group name 电子邮件 registerMessage group email 心情故事 group description value registerMessage group description 创建一个表单验证的模板 包含以下几个步骤 1 取得 form xml 中定义的 group 实例 set group form register defaultInstance 其中 register 为 group 的名字 2 创建 HTML 控件 包括 文本框 textarea 密码框等 但不管什么控件 都有一个 name 和一个 value 而我们 的任务是设置 name 和 value 例如 其中 id 为 group 中 field 的名字 请别忘了在 group id value 中加上感叹号 因为当 value 值为 null 时 Velocity 会直接显示成 group id value 而 group id value 就可以避免这种情形 3 显示错误信息 if group id valid group id message end 为了简化 我们写了一个 Velocity 宏 registerMessage 从而把这句话简化成 registerMessage group id 这样 我们就完成了这个表单 重启服务器 在浏览器上试一下 输入一些错误的值 看看会有什么反应 7 创建程序 创建程序 Action 是时候创建程序代码了 到目前为止 虽然我们没有写一行程序 但系统也工作得挺好 然而 有很多事情是做不了 的 例如 从数据库中读数据 或向数据库中写数据 在 Register 注册用户的例子中 当我们正确地填写了所有的字段 并提交时 数据不会自动存到数据库里去 现在我 们就来写一段程序 将数据保存到数据库中 不过为了读写数据库 我们还需要写业务层 数据访问层的代码 这些 我们将在另一篇教程中说明 在数据库可以被操作之前 我们先写一些空的代码 将来数据库就绪了 我们再把真实的代 码填进去 7 1 创建 model 类 SiteUser 为了将表单中 用户所填写的信息写入数据库 我们需要创建一个简单的 model 类 Model 就是 M V C 中的 Model 不过我们所要创建的 model 类的用处更广泛 它不仅在 WEB 层有用 而且也能在我们将来要介绍的业务层 数据访 问层中有用 Model 类是一个形式特别简单的普通 Java Bean Model 类不应该包含任何业务逻辑 model 只能作为信息的载体 请创建这个类 com alibaba workshop2 model SiteUser packagepackage com alibaba workshop2 model importimport mons lang builder ToStringBuilder publicpublic classclass SiteUser privateprivate String id privateprivate String password privateprivate String name privateprivate String email privateprivate String description publicpublic String getDescription returnreturn description publicpublic voidvoid setDescription String description thisthis description description publicpublic String getEmail returnreturn email publicpublic voidvoid setEmail String email thisthis email email publicpublic String getId returnreturn id publicpublic voidvoid setId String id thisthis id id publicpublic String getName returnreturn name publicpublic voidvoid setName String name thisthis name name publicpublic String getPassword returnreturn password publicpublic voidvoid setPassword String password thisthis password password publicpublic String toString returnreturn ToStringBuilder reflectionToString thisthis ToStringStyle MULTI LINE STYLE 这个类简单到只包含一些属性以及相关的 setter getter 因此在实践中 可以由代码生成器为我们代劳 来生成这些 简单而乏味的类 在 SiteUser 类的最后 我们利用 Apache Commons lang 工具包中的 ToStringBuilder 工具来生成对象的字符串描述 这 是为了调试的直观和方便 7 2 创建 action 类 SiteUserAction 请创建 SiteUserAction 类 packagepackage com alibaba workshop2 module action importimport com alibaba service form Form importimport com alibaba service form FormService importimport com alibaba service form Group importimport com alibaba service template TemplateContext importimport com alibaba turbine module action TemplateAction importimport com alibaba turbine service rundata RunData importimport com alibaba webx WebxException importimport com alibaba workshop2 model SiteUser publicpublic classclass SiteUserAction extendsextends TemplateAction publicpublic voidvoid doRegister RunData rundata TemplateContext context throwsthrows WebxException FormService forms FormService getWebxComponent getService FormService SERVICE NAME Form form forms getForm rundata ifif form isValid Group group form getGroup register SiteUser user newnew SiteUser group setProperties user FIXMEFIXME 保存到数据库中 System out println Registered user user 一般情况下 一个 Action 会从 TemplateAction 派生 在这个类里面 我们做了几件事 1 取得 FormService Action 的作用是将用户填写并提交的数据保存到数据库中 所以我们首先要从表单中取得用户填写的数据 我们前面 已经配置了 FormService 并用它来验证用户的输入 现在我们要取得 FormServ
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届国家管网集团高校毕业生招聘笔试备考试题(浓缩500题)及参考答案详解(培优b卷)
- 国家管网集团湖南公司2026届秋季高校毕业生招聘笔试模拟试题(浓缩500题)及答案详解(名师系列)
- 2026秋季国家管网集团建设项目管理公司高校毕业生招聘考试参考题库(浓缩500题)附参考答案详解(突破训练)
- 2026国家管网集团校园招聘(河北招17人)考试参考试题(浓缩500题)含答案详解(考试直接用)
- 2025国网陕西省高校毕业生提前批招聘(约450人)笔试模拟试题浓缩500题含答案详解(a卷)
- 2026国网甘肃省电力公司高校毕业生提前批招聘笔试参考题库浓缩500题附答案详解(达标题)
- 2026秋季国家管网集团湖南公司高校毕业生招聘4人笔试参考题库(浓缩500题)含答案详解(基础题)
- 2026秋季国家管网集团油气调控中心高校毕业生招聘14人笔试参考题库(浓缩500题)带答案详解(b卷)
- 2026秋季国家管网集团西部管道公司高校毕业生招聘笔试参考题库(浓缩500题)附参考答案详解(综合卷)
- 2026秋季国家管网集团广西公司高校毕业生招聘笔试备考题库(浓缩500题)含答案详解(a卷)
- 2025广东中山市公安局民众分局招聘辅警4人考试参考题库及答案解析
- 浙江省杭州市北斗联盟2024-2025学年高二上学期期中联考数学试题(教师版)
- 幕墙石材防护剂施工方案
- 2025至2030全球及中国绝缘体上硅(SOI)行业运营态势与投资前景调查研究报告
- 学堂在线 心理学与生活 章节测试答案
- 新22J01 工程做法图集
- 隧道施工工艺及施工技术课件
- 工程专项验收评审报告
- 胜任力模型及应用课件
- 重庆市专业技术人员继续教育登记卡(2022版)
- 115个低风险组病种目录
评论
0/150
提交评论