Top
  1. json Result
  2. 资费修改
  3. UI标签

1. json Result

1.1. 作用

1.1.1. json Result的作用

这种类型的result是用于向页面输出json格式的数据,它可以将json字符串输出到请求发起的位置。具体来说,是可以将Action中指定的属性做成json字符串输出。

这种result常被用于异步请求的情况,原因是异步请求由JS发起,并通过其回调函数接收服务端返回的结果。那么对于JS而言,我们返回Java对象它无法识别,返回json字符串就再合适不过了。

1.2. 使用方式

1.2.1. 语法

<result name="success” type=”json”>
	<param name=”root”>属性名</param>
</result>

这种方式,可以将Action中的一个属性做成json输出,其中

<result name="success” type=”json”>
	<param name=”includeProperties”>属性名1,属性名2,…</param>
</result>
<result name="success” type=”json”>
</result>

以上三种方式,我们重点掌握第一种即可。这种情况下,如果要输出多个数据,可以将这些数据封装于Map中输出。

1.2.2. 使用步骤

图-1

1.3. 名称唯一性校验

1.3.1. 需求描述

在资费新增页面,输入完资费名称后,进行光标切换时,验证资费名称是否重复,并在资费名称文本框后面给与相应提示。

1.3.2. 开发思路

对于资费名称是否唯一的校验,需要访问数据库才能判断出结果。然而这是在新增的过程中进行的校验,因此不能刷新页面,需要采用异步通信的方式来解决这类需求,即光标切换时发异步请求访问服务端,服务端根据传入的名称校验后将结果返回给浏览器,浏览器根据结果重新渲染局部的页面。

对于这个业务,首先要打开新增页面,然后再做唯一性校验,因此包含2种请求,即打开新增页面、名称唯一性校验。

图-2

图-3

1.3.3. 开发步骤

  1. 在struts.xml中配置新增页面的action。
  2. 创建新增页面。
  3. 在资费DAO中追加根据名称查询资费的方法。
  4. 创建资费名称唯一性校验Action,并定义输入属性为资费名,输出属性为校验提示信息,最后在业务方法中调用DAO,根据输入的资费名查询资费。判断查询结果,如果为空则给与正确的提示,否则给与错误的提示。
  5. 在struts.xml配置action。
  6. 重新部署项目,并在浏览器中直接访问当前校验的Action,看浏览器中显示的结果,来测试该校验方法。
  7. 在页面上使用JQuery发送异步请求访问此Action,并在回调函数中根据返回的结果给与用户示。

2. 资费修改

2.1. 开发思路

2.1.1. 需要几种请求

对于修改功能,需要处理2种类型的请求,首先要打开修改页面,这类似于打开新增页面。另外点击保存时需要对数据进行修改,这种请求类似于登录功能的表单提交,不同的是在提交的Action中调用DAO做修改保存而已。

对于后一种请求,由于没有涉及到我们新讲的知识点,因此作为扩展内容,大家尝试自行完成,后续的项目课中还会详细说明修改功能。

因此当前功能的要点就是第一种请求,即打开修改页面并显示默认的数据。对于打开修改页面,我们并不陌生,与打开登录页面、打开新增页面完全一致。那么重点就只有在修改页面上如何显示默认数据了。

我们可以使用Struts2的UI标签来很方便的在修改页面上显示出要修改的数据,这种方式可以称之为数据的回显。Struts2的UI标签可以帮助我们自动生成表单中的框体,并且同时可以为框体设置默认值。原则上我们应该先讲解UI标签,然后再完成修改功能,但由于UI标签比较多,学习起来有一定的难度,因此我们先在项目中直接使用一部分,在了了此种标签的用途之后,再回头详细的讲解每一类标签的用法,大家就容易理解了。

2.1.2. 打开修改页面的请求过程

如下图,打开修改页面的请求,我们需要编写代码的位置有DAO、Action、struts.xml、

JSP。

图-4

2.2. 开发步骤

2.2.1. 打开修改页面的开发步骤

3. UI标签

3.1. 作用

3.1.1. UI标签的作用

UI标签有很多种用法,其核心功能是生成表单框体以及给框体赋默认值,因此常用于修改的功能,但不局限于修改,因此在使用时需要灵活运用,当然在项目课中我们会带领代大家在多种场景下使用UI标签,以加强这方面的锻炼。

为了便于大家理解和记忆,我将UI标签进行了归类,分为简单的UI标签和复杂的UI标签。其中简单的UI标签很容易理解,基本上练习过一次之后就可以掌握,而复杂的UI标签在理解少略有难度,因此建议大家把重点放在复杂UI标签的学习上。

3.2. 简单的UI标签

3.2.1. 表单、提交按钮

1、表单

语法:

<s:form action="" method="" theme="simple">

</s:form>

说明:

该标记用于生成HTML的表单元素,其中theme用于指定主题,simple是简约主题,在生成时不会带有样式和表格。一般在项目中,我们都会将其设置为simple,原因是项目中的样式是界面工程师根据用户的需求统一制定的,不希望UI标签生成的样式对原有界面样式产生冲突。

2、提交按钮

语法:

<s:submit value="保存" />

说明:

该标记用于生成一个summit按钮。

3.2.2. 文本框、密码框、文本域

语法:

<s:textfield name="OGNL" />

说明:

该标记主要有2个作用,首先它会生成一个文本框,其次它会根据OGNL表达式访问ValueStack取值,并将取到的结果设置为文本框的默认值。

语法:

<s:password name="OGNL" />

说明:

密码框的作用完全与文本框一致,不同的是它生成了一个密码框。

语法:

<s:textarea name="OGNL" />

说明:

文本域的作用完全与文本框一致,不同的是它生成了一个文本域。

3.2.3. 布尔框

语法:

<s:checkbox name="OGNL" />

说明:

该标记主要有2个作用,首选是生成一个checkbox,其次它会根据OGNL表达式访问valueStack取值,这里取的值要求是一个布尔类型,然后会根据返回的结果,来设置checkbox是否勾选,显然如果返回值为true则勾选,否则不勾选。

3.3. 复杂的UI标签

3.3.1. 单选框

单选框的标签有2种使用方式,是按照单选框选项初始化方式的不同加以区分的。

语法:

<s:radio name="sex" list="#{'M':'男', 'F':'女'}/>

说明:该标签有2个作用

  1. 根据OGNL表达式创建的Map(#{'M':'男', 'F':'女'})生成一组单选框, Map中有几个键值对,就生成几个radio。其中Map的key用于生成radio的value值,Map的value用于生成radio的label显示值。
  2. 根据OGNL表达式(sex)访问ValueStack,并将返回的结果 与radio的value值比较,哪个radio的value值与返回结果一 致,则将该radio默认选中。

语法:

<s:radio name=“favoriteCity" list="cities" 
			listKey="cityCode" listValue="cityName"/>

说明:该标签有2个作用

  1. 根据OGNL表达式(cities)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组单选框。集合中有几个值,就生成几个radio。期间,会根据listKey指定的实体(City)属性来生成radio的value值,根据listValue指定的实体(City)属性来生成radio的显示值。
  2. 根据OGNL表达式(favoriteCity)访问ValueStack,并将返回的结果与radio的value值比较,哪个radio的value值返回结果一致,则该radio默认选中。

可见,2种使用方式在第一步初始化选项时有所区别,第一种是初始化为一个固定的值,第二种方式初始化的是动态的值,而对于设置单选框的默认选中,2者完全一致。

后面的多选框、下拉选,也都是这2种用法,与单选框的用法基本上一致。实际上无论是单选框、多选框及下拉选,其实都是选择框体,都是在多个选项的基础上选择一个或多个值,只是表现形式不同而已,所以这3种框体的标签在用法上十分的相似,大家重点理解单选框,那么其他2种框体自然也就容易理解了。

3.3.2. 多选框

语法:

<s:checkboxlist name=“travelCities" 
		 list="#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' }"/>

说明:

  1. 根据OGNL表达式创建的Map(#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' })生成一组多选框,Map中有几个键值对,就生成几个checkbox。其中Map的key用于生成checkbox的value值,Map的value用于生成checkbox 的label显示值。
  2. 根据OGNL表达式(travelCities)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox 默认选中。

语法:

<s:checkboxlist name=“travelCities" list="cities" 
			listKey="cityCode" listValue="cityName"/>

说明:

  1. 根据OGNL表达式(cities)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组多选框。集合中有几个值,就生成几个checkbox。期间,会根据listKey指定的实体(City)属性来生成checkbox的value值,根据listValue指定的实体(City)属性来生成checkbox的显示值。
  2. 根据OGNL表达式(travelCities)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox 默认选中。

3.3.3. 下拉选

语法:

<s:select name="home" 
		 list="#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' }"/>

说明:

  1. 根据OGNL表达式创建的Map(#{'01':'北京', '02':'上海', '03':'广州', '04':'深圳' })生成一组多选框,Map中有几个键值对,就生成几个checkbox。其中Map的key用于生成checkbox的value值,Map的value用于生成checkbox 的label显示值。
  2. 根据OGNL表达式(home)访问ValueStack,访问的属性为集合(List<String>),并将返回的结果与checkbox的value值比较,哪个checkbox的value值在返回结果的集合中,则该checkbox默认选中。

语法:

<s:select name="home" list="cities" 
			listKey="cityCode" listValue="cityName"/>

说明:

  1. 根据OGNL表达式(蓝色)访问ValueStack,访问的属性应为集合(List<City>),并根据返回结果生成一组下拉选。集合中有几个值,就生成几个option。期间,会根据listKey指定的实体(City)属性来生成option的value值,根据listValue指定的实体(City)属性来生成option的显示值。
  2. 根据OGNL表达式(红色)访问ValueStack,并将返回的结果与option的value值比较,哪个option的value值与返回结果一致,则该option默认选中。