jsf xhtml调用方法_JSF的工作方式以及调试方法–可以使用polyglot吗?

jsf xhtml调用方法

JSF不是我们通常认为的那样。 这也是一个调试起来可能有些棘手的框架,尤其是在初次遇到时。 在这篇文章中,让我们继续探讨为什么会出现这种情况,并提供一些JSF调试技术。 我们将讨论以下主题:

  • JSF不是我们经常想到的
  • JSF调试的难点
  • 如何系统地调试JSF
  • JSF的工作原理– JSF生命周期
  • 从浏览器调试Ajax请求到服务器再返回
  • 调试JSF前端Javascript代码
  • 最后的想法–替代方案? (给读者的问题)

JSF不是我们经常想到的

首先,JSF看起来像一个企业Java / XML前端框架,但实际上并不是 。 它实际上是一个多语言Java / Java脚本框架,其中客户端Java脚本部分不可忽略,理解它也很重要。 它还对直接使用HTML / CSS有很好的支持。

JSF开发人员正在使用ocasion,而他们已经是多种语言的开发人员,其主要语言是Java,但仍需要使用本地语言的Javascript。

JSF调试的难点

在上一篇文章中将JSF与GWT和AngularJS进行比较时 ,我发现该框架从XML背后的开发人员那里提取HTML和CSS的(最常用的)方法增加了调试的难度,因为它创建了一个额外的层次。间接。

也可以使用直接使用HTML / CSS的更直接的方法 ,但是似乎企业Java开发人员在大多数情况下倾向于使用XML,因为它是一种更熟悉的技术。 另一个问题是框架/库的客户端Javascript部分没有很好的文档记录,了解发生的事情通常很重要。

系统调试JSF的唯一方法

第一次遇到JSF时,我首先尝试仅从Java,XML和文档中使用它。 虽然我可以那样做一部分工作,但在很多情况下这种方法确实是不够的。

我得出的结论是,为了能够有效地调试JSF应用程序,需要了解以下内容:

  • HTML
  • CSS
  • Java脚本
  • HTTP
  • Chrome开发工具,Firebug或同等功能
  • JSF生命周期

对于大多数使用Java / XML进行工作的开发人员来说,这听起来可能令人惊讶,但是这种以Web为中心的调试JSF的方法是我设法满足许多需要一些重要组件自定义或能够修复某些bug的唯一方法。

让我们首先了解JSF的内部工作原理,以便我们可以对其进行更好的调试。

JSF接受MVC

JSF处理MVC的方式是全部三个组件都位于服务器端:

  • 该模型是纯Java对象的树
  • 视图是用XML定义的服务器端模板,读取该模板即可构建内存视图定义
  • Controller是一个Java Servlet,它接收每个请求并通过一系列步骤处理它们

假定浏览器只是服务器端生成HTML的呈现引擎。 通过提交页面的一部分以进行服务器处理,并请求服务器仅在不离开页面的情况下“重绘”屏幕的某些部分,即可实现Ajax。

JSF生命周期

HTTP请求到达后端后,将被JSF Controller捕获,然后将对其进行处理。 该请求经历了称为JSF生命周期的一系列阶段,这对于理解JSF的工作方式至关重要:

jsfIntro-lifecycle

JSF生命周期的设计目标

整个生命周期的重点是仅使用浏览器作为渲染平台,在服务器端100%管理MVC。

最初的想法是使呈现平台与服务器端UI组件模型脱钩,以便通过交换“呈现响应”阶段来使用替代标记语言替换HTML。

这是在2000年代初期,当时HTML很快就可以被基于XML的替代方法取代(从未出现过),然后HTML5出现了。 浏览器的功能要比当今更加强大,并且跨浏览器Javascript库的想法尚未普及。

因此,让我们遍历每个阶段,并从浏览器开始,看看是否需要调试它。 让我们以使用Ajax请求的简单示例为基础。

JSF 2 Hello World示例

以下是最小的JSF 2页面,该页面接收来自用户的输入文本,通过Ajax请求将文本发送到后端,并仅刷新输出标签:

<h:body>  <h3>JSF 2.2 Hello World Example</h3><h:form><h:outputtext id="output" value="#{simpleFormBean.inputText}"></h:outputtext>  <h:inputtext id="input" value="#{simpleFormBean.inputText}"></h:inputtext><h:commandbutton value="Submit" action="index"><f:ajax execute="input" render="output"></f:ajax></h:commandbutton></h:form>
</h:body>

该页面如下所示:

你好,世界

遵循一个Ajax请求–发送至服务器并返回

让我们单击提交以触发Ajax请求,然后使用Chrome开发工具网络标签(右键单击并检查页面上的任何元素)。 这是我们在请求的“表单数据”部分中看到的:

j_idt8:input: Hello World   
javax.faces.ViewState: -2798727343674530263:954565149304692491   
javax.faces.source: j_idt8:j_idt9
javax.faces.partial.event: click
javax.faces.partial.execute: j_idt8:j_idt9 j_idt8:input
javax.faces.partial.render: j_idt8:output
javax.faces.behavior.event: action
javax.faces.partial.ajax:true

该请求说:

输入字段的新值是“ Hello World”,仅向我发送输出字段的新值,请勿浏览此页面。

让我们看看如何从请求中读取它。 如我们所见,表单的新值被提交到服务器,即“ Hello World”值。 这是几个条目的含义:

  • javax.faces.ViewState标识从其发出请求的视图。
  • 该请求是一个Ajax请求,如标志javax.faces.partial.ajax
  • 该请求是由javax.faces.partial.event定义的单击触发的。

但是那些j_字符串是什么? 这些是用空格分隔生成HTML元素标识符。 例如,这是我们使用Chrome开发工具查看与j_idt8:input对应的页面元素的方式:

img2_component_ids

还有3个额外的表单参数使用这些标识符,这些参数链接到UI组件:

  • javax.faces.source :发起此请求HTML元素的标识符,在本例中为Submit按钮的ID。
  • javax.faces.execute :元素的标识符列表,这些元素的值发送到服务器进行处理,在本例中为输入文本字段。
  • javax.faces.render :页面上要“重画”的部分的标识符列表,在这种情况下,仅输出字段。

但是,当请求到达服务器时会发生什么呢?

JSF生命周期–还原视图阶段

请求到达服务器后,JSF控制器将检查
javax.faces.ViewState并标识它引用的视图。 然后它将构建或恢复视图的Java表示,该表示与浏览器端的文档定义某种程度上相似。

该视图将附加到请求并在整个过程中使用。 通常在应用程序开发期间几乎不需要调试此阶段。

JSF生命周期–应用请求值

然后,JSF控制器将通过请求接收到的新值应用于视图小部件。 该值此时可能无效。 在此阶段,每个JSF组件都会调用其decode方法。

此方法将从HTTP请求中检索相关小部件的提交值,并将其存储在小部件本身上。

为了调试它,让我们在HtmlInputText类的decode方法中放置一个断点,以查看值“ Hello World”:

img4_debug_ARV

注意使用我们想要的字段HTML clientId的条件断点。 这样,即使在带有许多其他相似小部件的大页面中,也可以仅快速调试所需组件的解码。 解码之后的下一个步骤是验证阶段。

JSF生命周期–流程验证

在此阶段,将应用验证,如果发现值有误(例如,日期无效),则请求将绕过“调用应用程序”并直接进入“渲染响应”阶段。

要调试此阶段,可以在processValidators方法上放置一个类似的断点,或者如果您碰巧知道哪些是自定义的,则可以在验证器中放置一个断点。

JSF生命周期–更新模型

在此阶段,我们知道所有提交的值都是正确的。 现在,JSF可以通过将请求中接收到的新值应用于视图模型中的纯Java对象来更新视图模型。

可以通过在有问题的组件的processUpdates方法中放置一个断点,最终使用类似的条件断点仅在所需的组件上进行破坏,来调试此阶段。

JSF生命周期–调用应用程序

这是最简单的调试阶段。 该应用程序现在具有更新的视图模型,并且可以在其上应用一些逻辑。

这是在XML视图定义中定义的动作侦听器(“动作”属性和侦听器标记)被执行的地方。

JSF生命周期–渲染响应

这是我最后调试最多的阶段:为什么未按预期显示该值,等等,都可以在这里找到。 在此阶段,视图和新模型值将从Java对象转换为HTML,CSS和最终的Javascript,并通过电线发送回浏览器。

可以使用相关组件的encodeBeginencodeChildrenencodeEnd方法中的断点来调试此阶段。

组件将自己渲染或将渲染委托给Renderer类。

返回浏览器

这是一段漫长的旅程,但我们回到了起点! 这是在浏览器中收到JSF生成的响应后的样子:

<!--?xml version='1.0' encoding='UTF-8'?--> 
<partial-response>  <changes><update id="j_idt8:output"><span id="j_idt8:output"></span></update><update id="javax.faces.ViewState">-8188482707773604502:6956126859616189525></update></changes>
</partial-response>

框架的Javascript部分将要做的是获取部分响应的内容,并逐个更新。

使用更新的ID,客户端JSF回调将搜索具有该ID的组件,将其从文档中删除,然后将其替换为新的更新版本。

在这种情况下,“ Hello World”将显示在“输入”文本字段旁边的标签上!

因此,这就是JSF在后台运行的方式。 但是,如果我们需要调试框架的Javascript部分,该怎么办?

调试JSF Javascript代码

Chrome开发工具可以帮助调试客户端。 例如,假设我们要在触发Ajax请求时暂停客户端。 我们需要转到“源”选项卡,添加XHR(Ajax)断点并触发浏览器操作。 调试器将停止,并且可以检查调用堆栈:

debug_frontend

对于Primefaces之类的某些框架,可能会缩小Javascript源(人类不可读),因为它们针对大​​小进行了优化。

为了解决这个问题,请下载该库的源代码,并以最小的方式构建jar。 通常对此有说明,否则请检查项目poms。 这将在您的Maven资源库中安装一个具有非压缩源的jar进行调试。

UI调试标签:

ui:debug标记允许使用键盘快捷键查看许多调试信息,有关更多详细信息,请参见此处 。

最后的想法

JSF在企业Java世界中非常流行,并且可以很好地处理许多问题,特别是在UI设计人员考虑使用小部件库的可能性的情况下。

问题在于,通常会有功能请求迫使我们深入研究小部件的内部实现以对其进行自定义,这需要HTML,CSS,Javascript和HTTP以及JSF生命周期知识。

杂音是替代品吗?

我们想知道,如果开发人员必须对Web技术有足够的了解,以便能够有效地调试JSF,那么使用这些技术直接构建企业前端(仅是客户端部分)会更简单。

可能会在不久的将来证明Java后端加上仅Javascript前端的多语言方法是有效的,特别是使用某种客户端MVC框架(例如Angular) 。

这将需要学习更多的Javascript(如果好奇的话,可以看一下Java开发人员的Javascript ),但是无论如何,这对于在JSF中进行自定义小部件开发通常是必需的。

结论和一些疑问(如果有时间的话)

感谢您的阅读,请花点时间在下面的评论中分享您对这些问题的看法:

  • 您是否认为多语种开发(Java / Javascript)通常是可行的选择,尤其是在您的工作场所中?
  • 您是否发现基于GWT的框架之一(普通GWT,Vaadin,Errai)或Play框架更易于使用且生产率更高?

翻译自: https://www.javacodegeeks.com/2014/09/how-jsf-works-and-how-to-debug-it-is-polyglot-an-alternative.html

jsf xhtml调用方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/339746.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 分别编译_Java源文件和编译后的文件扩展名分别为()_学小易找答案

【单选题】( )下列关于逻辑运算符AND,描述正确的是哪一项?【单选题】如果声明一个类时使用abstract修饰符,则表明该类是()【填空题】要查询student表中name字段值以字符“m”开始,以字符“d”结束的记录应该在WHERE子句后跟 LIKE________。【填空题】不允许在关系中出现重复记…

将Auth0 OIDC(OAUTH 2)与授权(组和角色)集成

如果您正在使用Auth0对多个现有应用程序中的用户进行身份验证和授权&#xff0c;则可能需要将下一个Web应用程序与Auth0集成。 有多种方法可以执行此操作&#xff0c;例如&#xff0c;如果要将Jenkins与Auth0集成&#xff0c;则可以使用SAML v2&#xff1b;否则&#xff0c;可…

power of two java_LeetCode算法题-Power Of Two(Java实现)

这是悦乐书的第194次更新&#xff0c;第200篇原创01 看题和准备今天介绍的是LeetCode算法题中Easy级别的第56题(顺位题号是231)。给定一个整数&#xff0c;写一个函数来确定它是否是2的幂。例如&#xff1a;输入&#xff1a;1输出&#xff1a;true说明&#xff1a;2^0 1输入&a…

tomee_一罐将其全部统治:Apache TomEE + Shrinkwrap == JavaEE引导

tomee警告&#xff1a;我不是Spring Boot的专家。 我发现很多事情对此非常有趣&#xff0c;并且当然可以真正改善您的日常工作。 而且&#xff0c;我对Spring Boot没有任何反对&#xff0c;也没有开发或使用它的人。 但是我认为社区高估了该产品。 一年前&#xff0c;我开始收…

java比较equlse_java基础知识要点

一、抽象&#xff1a;二、封装&#xff1a;有了封装才有数据类型&#xff01;个体更多的设置为封装体&#xff0c;这样更加安全。该公开的公开(方法)&#xff0c;该隐藏的隐藏(属性)&#xff0c;配置一个访问窗口方法的调用(按值传递和按引用传递)1、在栈中分配空间(暂时给方法…

使用Spring Boot和Project Reactor处理SQS消息

我最近参与了一个项目&#xff0c;在该项目中&#xff0c;我不得不有效地处理通过AWS SQS Queue流入的大量消息。 在这篇文章&#xff08;可能还有一篇&#xff09;中&#xff0c;我将介绍使用出色的Project Reactor处理消息的方法。 以下是我要进行的设置&#xff1a; 设置本…

java commons lang 随机数_Apache Common-lang组件里随机数工具类RandomStringUtils的一个bug...

现在本文也转到了我自己的博客上&#xff0c;地址&#xff1a;月城小馆Apache Common组件是java开发中常用的工具&#xff0c;其中的common-lang包是java基本数据类型的处理工具&#xff0c;包括数字、字符串、日期时间等多种工具类。在org.apache.commons.lang包中有一个随机数…

初级测试开发面试题_初级开发人员在编写单元测试时常犯的错误

初级测试开发面试题自从我编写第一个单元测试以来已经有10年了。 从那时起&#xff0c;我不记得我已经编写了成千上万的单元测试。 老实说&#xff0c;我在源代码和测试代码之间没有任何区别。 对我来说是同一回事。 测试代码是源代码的一部分。 在过去的3-4年中&#xff0c;我…

java文件读写详细介绍_java文件读写操作大全

一.获得控制台用户输入的信息public String getInputMessage() throws IOException...{System.out.println("请输入您的命令∶");byte buffer[]new byte[1024];int countSystem.in.read(buffer);char[] chnew char[count-2];//最后两位为结束符&#xff0c;删去不要f…

使用SoapUI调用安全WCF SOAP服务–第1部分,该服务

在这个由三部分组成的传奇中&#xff0c;我将演示如何使用SoapUI API工具来调用安全的SOAP服务。 首先&#xff0c;我将专注于创建服务&#xff0c;在接下来的文章中它将充当被测系统。 使用基本身份验证传输安全性机制维护对该服务中资源的访问。 Windows Communication Foun…

java简单系统_Java简单学生管理系统

Java简单学生管理系统这个不需要手动输入&#xff0c;笔记记录//studentpublic class student(){private String id;//学号private String name;//姓名private int age;//年龄public String getId() {return id;}public void setId(String id) {this.id id;}public String get…

github和maven_在github上托管Maven存储库(包含源代码和javadoc)

github和maven如何通过maven使其他开发人员可以使用小型开源库&#xff1f; 一种方法是将其部署在Maven Central Repository上 。 我想要做的是将其部署到github &#xff0c;因此我可以自由地对其进行修改。 这篇文章将告诉您如何做到这一点。 我将工件部署到github的典型方法…

kafka java编程demo_Kafka简单客户端编程实例

今天&#xff0c;我们给大家带来一篇如何利用Kafka的API进行客户端编程的文章&#xff0c;这篇文章很简单&#xff0c;就是利用Kafka的API创建一个生产者和消费者&#xff0c;生产者不断向Kafka写入消息&#xff0c;消费者则不断消费Kafka的消息。下面是具体的实例代码。一、创…

java我的世界极限生存_我的世界 1.7.10 极限生存整合包

整合包介绍&#xff1a;最近总有人觉得Minecraft很无聊&#xff0c;没有什么可玩的&#xff0c;或者觉得生存太简单 那么就来试试这个吧&#xff0c;全部是增强怪物的MOD&#xff0c;保证不无聊&#xff0c;保证不简单 基本上没有增加一些新的东西&#xff0c;只增加了几种怪物…

具有InlfuxDB的Spring Boot和Micrometer第1部分:基础项目

对于那些关注此博客的人来说&#xff0c;难怪我倾向于大量使用InfluxDB。 我喜欢这样一个事实&#xff0c;它是一个真正的单一用途的数据库&#xff08;时间序列&#xff09;&#xff0c;具有许多功能&#xff0c;并且还带有企业支持。 Spring也是我选择的工具之一。 因此&…

Gradle善良:仅添加包装用于战争

我的同事Tom Wetjens 在Maven中撰写了博客文章仅打包依赖项 。 当我们想在WAR文件中包含依赖项时&#xff0c;他展示了一种Maven解决方案&#xff0c;而在其他任何作用域中都没有使用。 在这篇博客中&#xff0c;我们将看到我们如何在Gradle中解决这个问题。 假设我们在项目中…

java递归api_javaAPI_IO流基础_递归使用

IO流_递归1.递归概述递归指的是方法定义中调用自身方法的情况。2.递归的注意事项(1).要有出口&#xff0c;否则就是死递归(2).次数不能太多&#xff0c;否则就内存溢出(3).构造方法不能递归使用[不然在创建对象的时候就会内存溢出]3.递归解决问题的思想(1).分解法:把问题细分为…

PIT,JUnit 5和Gradle –仅需额外的一行配置

在Gradle&#xff08;带有gradle-pitest-plugin 1.4.7&#xff09;中发现简单&#xff0c;经过改进的PIT和JUnit 5配置。 不可否认&#xff0c;如今JUnit 5越来越受欢迎。 虽然为JUnit 5提供了一个专用于PIT的插件&#xff0c;并且gradle-pitest-plugin支持了很多年&#xff0…

apache camel_使用WildFly 8在Java EE7中自举Apache Camel

apache camel从Camel版本2.10开始&#xff0c;支持CDI&#xff08;JSR-299&#xff09;和DI&#xff08;JSR-330&#xff09;。 这为在Java EE容器中以及在独立的Java SE或CDI容器中开发和部署Apache Camel项目提供了新的机会。 是时候尝试一下并熟悉它了。 骆驼到底是什么&am…

python中可变参数怎么传递的呢_在python中,你可以在命名参数后传递可变参数吗?...

can you pass variadic arguments after named parameters?Python 3.4.3&#xff1a;答案是肯定的.如果要调用仅命名固定参数的函数,请将可变参数放在函数定义中def function(*args, bob, sally):print(args, bob, sally)values [1, 2, 3, 4]function(bob"Hi bob",…