jsf服务_使用JSF的面向服务的UI

jsf服务

在大型软件开发项目中,面向服务的体系结构非常常见,因为它提供了可供不同团队或部门使用的功能接口。 创建用户界面时,应应用相同的原理。
对于具有开票部门和客户管理部门等的大型公司,组织结构图可能如下所示:

如果计费部门要开发一个用于创建发票的新对话框,则可能如下所示:

如您所见,上面的屏幕在上部引用了一个客户。 单击短名称文本字段后面的“ ..”按钮将打开以下对话框,允许用户选择客户:

按“选择”后,客户数据将显示在发票表格中。

也可以通过简单地输入客户编号或在发票屏幕上的文本字段中输入简称来选择客户。 如果输入了唯一的短名称,则根本不会出现选择对话框。 而是直接显示客户数据。 只有不明确的简称会导致打开客户选择屏幕。

客户功能将由属于客户管理团队的开发人员提供。 一种典型的方法是由客户管理开发团队提供一些服务,而计费部门的开发人员创建用户界面并调用这些服务。

但是,这种方法需要在这两个不同部门之间建立更强的耦合,而不是实际需要的耦合。 发票只需要一个唯一的ID即可引用客户数据。 创建发票对话框的开发人员实际上并不想知道如何查询客户数据或在后台使用哪些服务来获取该信息。

客户管理开发人员应提供UI的完整部分,以显示客户ID并处理客户的选择:

使用JSF 2,使用复合组件很容易实现。 客户管理部门和计费部门之间的逻辑接口包括三个部分:

  • 复合组件(XHTML)
  • 复合组件的支持bean
  • 侦听器界面,用于处理选择结果


提供者(客户管理部门)

复合组件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"xmlns:ui="http://java.sun.com/jsf/facelets"xmlns:h="http://java.sun.com/jsf/html"xmlns:f="http://java.sun.com/jsf/core"xmlns:composite="http://java.sun.com/jsf/composite"xmlns:ice="http://www.icesoft.com/icefaces/component"xmlns:ace="http://www.icefaces.org/icefaces/components"xmlns:icecore="http://www.icefaces.org/icefaces/core"><ui:composition><composite:interface name="customerSelectionPanel" displayName="Customer Selection Panel" shortDescription="Select a customer using it's number or short name"><composite:attribute name="model" type="org.fuin.examples.soui.view.CustomerSelectionBean" required="true" />  </composite:interface><composite:implementation><ui:param name="model" value="#{cc.attrs.model}"/><ice:form id="customerSelectionForm"><icecore:singleSubmit submitOnBlur="true" /><h:panelGroup id="table" layout="block"><table><tr><td><h:outputLabel for="customerNumber"value="#{messages.customerNumber}" /></td><td><h:inputText id="customerNumber"value="#{model.id}" required="false" /></td><td>&nbsp;</td><td><h:outputLabel for="customerShortName"value="#{messages.customerShortName}" /></td><td><h:inputText id="customerShortName"value="#{model.shortName}" required="false" /></td><td><h:commandButton action="#{model.select}"value="#{messages.select}" /></td></tr><tr><td><h:outputLabel for="customerName"value="#{messages.customerName}" /></td><td colspan="5"><h:inputText id="customerName"value="#{model.name}" readonly="true" /></td></tr></table></h:panelGroup></ice:form></composite:implementation></ui:composition></html>

复合组件的后备bean:

package org.fuin.examples.soui.view;import java.io.Serializable;import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;import org.apache.commons.lang.ObjectUtils;
import org.fuin.examples.soui.model.Customer;
import org.fuin.examples.soui.services.CustomerService;
import org.fuin.examples.soui.services.CustomerShortNameNotUniqueException;
import org.fuin.examples.soui.services.UnknownCustomerException;@Named
@Dependent
public class CustomerSelectionBean implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String shortName;private String name;private CustomerSelectionListener listener;@Injectprivate CustomerService service;public CustomerSelectionBean() {super();listener = new DefaultCustomerSelectionListener();}public Long getId() {return id;}public void setId(final Long id) {if (ObjectUtils.equals(this.id, id)) {return;}if (id == null) {clear();} else {clear();this.id = id;try {final Customer customer = service.findById(this.id);changed(customer);} catch (final UnknownCustomerException ex) {FacesUtils.addErrorMessage(ex.getMessage());}}}public String getShortName() {return shortName;}public void setShortName(final String shortNameX) {final String shortName = (shortNameX == "") ? null : shortNameX;if (ObjectUtils.equals(this.shortName, shortName)) {return;}if (shortName == null) {clear();} else {if (this.id != null) {clear();}this.shortName = shortName;try {final Customer customer = service.findByShortName(this.shortName);changed(customer);} catch (final CustomerShortNameNotUniqueException ex) {select();} catch (final UnknownCustomerException ex) {FacesUtils.addErrorMessage(ex.getMessage());}}}public String getName() {return name;}public CustomerSelectionListener getConnector() {return listener;}public void select() {// TODO Implement...}public void clear() {changed(null);}private void changed(final Customer customer) {if (customer == null) {this.id = null;this.shortName = null;this.name = null;listener.customerChanged(null, null);} else {this.id = customer.getId();this.shortName = customer.getShortName();this.name = customer.getName();listener.customerChanged(this.id, this.name);}}public void setListener(final CustomerSelectionListener listener) {if (listener == null) {this.listener = new DefaultCustomerSelectionListener();} else {this.listener = listener;}}public void setCustomerId(final Long id) throws UnknownCustomerException {clear();if (id != null) {clear();this.id = id;changed(service.findById(this.id));}}private static final class DefaultCustomerSelectionListener implementsCustomerSelectionListener {@Overridepublic final void customerChanged(final Long id, final String name) {// Do nothing...}}}

用于处理结果的侦听器接口:

package org.fuin.examples.soui.view;/*** Gets informed if customer selection changed.*/
public interface CustomerSelectionListener {/*** Customer selection changed.** @param id New unique customer identifier - May be NULL.* @param name New customer name - May be NULL.*/public void customerChanged(Long id, String name);}

用户(计费部门)

发票Bean只是通过注入来使用客户选择Bean,并使用侦听器接口连接到它:

package org.fuin.examples.soui.view;import java.io.Serializable;import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.New;
import javax.inject.Inject;
import javax.inject.Named;@Named("invoiceBean")
@SessionScoped
public class InvoiceBean implements Serializable {private static final long serialVersionUID = 1L;@Inject @Newprivate CustomerSelectionBean customerSelectionBean;private Long customerId;private String customerName;@PostConstructpublic void init() {customerSelectionBean.setListener(new CustomerSelectionListener() {@Overridepublic final void customerChanged(final Long id, final String name) {customerId = id;customerName = name;}});}public CustomerSelectionBean getCustomerSelectionBean() {return customerSelectionBean;}public String getCustomerName() {return customerName;}}

最后,在发票XHTML中,使用了复合组件并将其链接到注入的支持bean:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"xmlns:ui="http://java.sun.com/jsf/facelets"xmlns:h="http://java.sun.com/jsf/html"xmlns:f="http://java.sun.com/jsf/core"xmlns:fuin="http://fuin.org/examples/soui/facelets"xmlns:customer="http://java.sun.com/jsf/composite/customer"><ui:composition template="/WEB-INF/templates/template.xhtml"><ui:param name="title" value="#{messages.invoiceTitle}" /><ui:define name="header"></ui:define><ui:define name="content"><customer:selection-panel model="#{invoiceBean.customerSelectionBean}" /></ui:define><ui:define name="footer"></ui:define></ui:composition></html>

摘要
总之,用户界面中引用其他部门数据的部分应由提供数据的部门负责。 然后,可以很容易地对提供的代码进行任何更改,而无需对使用代码进行任何更改。 此方法的另一个重要好处是协调应用程序的用户界面。 显示相同数据的控件和面板始终看起来相同。 每个部门还可以为其提供的用户界面组件创建一个存储库,从而使设计新对话框的过程像将正确的组件放在一起一样容易。

参考: A Java Developer's Life博客上的JCG合作伙伴 Michael Schnell提供的面向服务的UI 。


翻译自: https://www.javacodegeeks.com/2012/09/service-oriented-ui-with-jsf.html

jsf服务

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

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

相关文章

MATLAB矩阵对称旋转

fliplr(a) 矩阵左右翻转 flipud(a) 矩阵上下翻转 rot90(a)矩阵逆时针旋转90度&#xff08;把你的头顺时针旋转90看原数就可以知道结果了,^-^&#xff09;rot90(a,k) k参数定义为逆时针旋转90*k度。

English trip -- Phonics 3 元音字母e

xu言&#xff1a; 额...今天给我上自然拼读的maple老师 - . -和上次给我上第二集自然拼读的是同一个老师。突然考了考我上次学的内容~感觉大脑一片空白。看来review不能光说而不下苦功夫啊... 元音 vowel 长音 /i:/ be me we he chinese ee meet bee see sleep queen …

生成随机测试数据的文件的程序

例如以下简单的AB问题&#xff1a; 样例 输入&#xff1a; 1 2 输出&#xff1a; 3 答案&#xff1a; #include <stdio.h> int main() {int a,b;while(scanf("%d%d",&a,&b)!EOF){printf("%d\n",ab);}return 0; }机器的测试&#xff1a;…

ANTLR和Jetbrains MPS:解析文件并以树符号显示AST

Itemis再次这样做&#xff1a;他们刚刚为Jetbrains MPS发布了一个非常酷的新插件。 这允许定义新的树编辑器。 他们看起来像这样&#xff1a; 在这篇文章中&#xff0c;我们将看到&#xff1a; 如何在MPS中使用ANTLR解析器 如何使用树符号表示已解析的AST 特别是&#xf…

MATLAB判断矩阵相等

1. AB;%得到的是一个矩阵&#xff0c;对应值相等则返回1&#xff0c;否则返回02. ~norm(A-B);%若AB则A-B全零&#xff0c;norm(A-B)的结果为0&#xff0c;否则为1&#xff1b;其中norm为范数3. ~sum(sum(abs(A-B)));%原理和2相同&#xff0c;但是计算速度要快于2数倍 4. isequ…

python全栈-Day 1

Python是一种动态强类型解释型语言 1、Python历史 Python2与Python3的区别&#xff1a; Python2&#xff1a; 源码不标准&#xff0c;混乱&#xff0c;重复代码多 默认编码方式是ASCII码&#xff0c;因此需要在文件的首行 #-*- encoding:utf-8 -*- Python3&#xff1a; 统一标准…

KMP字符串模式匹配详解

刚看到位兄弟也贴了份KMP算法说明&#xff0c;但本人觉得说的不是很详细&#xff0c;当初我在看这个算法的时候也看的头晕昏昏的&#xff0c;我贴的这份也是网上找的。且听详细分解&#xff1a;KMP字符串模式匹配详解 来自CSDN A_B_C_ABC 网友 KMP字符串模式匹配通俗点说…

Matlab找矩阵中最大最小值的位置

1. ind find(Amin(min(A)));2. [row,column]find(Amin(min(A)));

ASP.NET Core IdentityServer4 新手上路

OAuth2.0资料 今天看到一篇博主写了该系列文章,贴图和过程都比较详细,俗话说实践是检验真理的唯一标准&#xff08;如果是按照参考文章复制粘贴,应该不会出现踩坑&#xff0c;但是我喜欢自己手动敲一遍&#xff09;&#xff0c;发现几个坑&#xff0c;因而总结下经验&#xff0…

MATLAB矩阵复制数据

如果想让矩阵A(m,n)的数据的每一行复制b遍&#xff0c;组成一个m*b行的大矩阵&#xff0c;可以用B A(reshape(ones(b,1)*(1:m),m*b,1),:);

博弈知识汇总

以下是我从网上收集的关于组合博弈的资料汇总&#xff1a; 有一种很有意思的游戏&#xff0c;就是有物体若干堆&#xff0c;可以是火柴棍或是围棋子等等均可。两个 人轮流从堆中取物体若干&#xff0c;规定最后取光物体者取胜。这是我国民间很古老的一个游戏 &#xff0c;别看这…

主成分分析和因子分析区别与联系

主成分分析可以简单的总结成一句话&#xff1a;数据的压缩和解释。常被用来寻找判断某种事物或现象的综合指标&#xff0c;并且给综合指标所包含的信息以适当的解释。在实际的应用过程中&#xff0c;主成分分析常被用作达到目的的中间手段&#xff0c;而非完全的一种分析方法。…

MATLAB空矩阵

创建空矩阵a [];%[]表示为空a zeros(m,n);%创建m*n的全零矩阵&#xff0c;不同于空矩阵判断空矩阵isempty(a);判断a是不是空矩阵

将Spring Boot应用程序绑定到Cloud Foundry中的服务的方法

如果要试用Cloud Foundry &#xff0c;最简单的方法是下载出色的PCF开发人员或在Pivotal Web Services站点上创建试用帐户。 文章的其余部分假定您已经安装了Cloud Foundry&#xff0c;并且对Cloud Foundry有较高的了解。 这篇文章的目的是列出将Java应用程序集成到服务实例中…

matlab里插入行和列

matlab里插入行和列>> Amagic(4)A 16 2 3 135 11 10 89 7 6 124 14 15 1>> b1:4b 1 2 3 4>> C[A(1:2,:) ; b ; A(3:end,:)] % 行向量b插入第2行和第3行之间C 16 2 3 135 11 10 …

博弈问题及SG函数(真的很经典)

博弈问题 若你想仔细学习博弈论&#xff0c;我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材&#xff0c;它使我受益太多。&#xff08;如果你的英文水平不足以阅读它&#xff0c;我只能说&#xff0c;恐怕你还没到需要看“博弈论”的时候。&am…

luogu P1519 穿越栅栏 Overfencing

题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是&#xff0c;他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是&#xff0c;他所建造的迷宫是一个“完美的”迷宫&#xff1a;即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷…

Matlab reshape重新排布数组

使用reshape需要保证前后调整后的元素个数一致,否则会报错

hibernate关联映射_具有关联映射的Hibernate Composite ID

hibernate关联映射最近&#xff0c;我们面临着带有复合id字段的Hibernate关联映射的棘手情况。 我们需要与一对一和多对一进行双向关联。我们的拖曳表是“ REPORT”和“ REPORT_SUMMARY”&#xff0c;它们之间具有从REPORT到REPORT_SUMMARY的一对多关系&#xff0c;而从REPORT_…

css实现简单的告警提示动画效果

需求&#xff1a;css实现简单的告警提示动画效果&#xff0c;当接收到实时信息的时候&#xff0c;页面弹出告警信息的动画效果<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>css实现告警提示动画</…