从标签时代到富客户端:从Web 1.0到Flex

FLEX网站源码完整项目实战解析 MXML 文件必须严格遵守 XML 的良好格式要求:有且仅有一个根元素,所有标签闭合,属性使用双引号包围。其典型结构如下所示:-- 非可视元素声明 --><s:VGroup>在此结构中,xmlns属性定义了命名空间前缀与 URI 的映射关系:xmlns:fx:指向 Adobe MXML 元数据和核心语言元素(如xmlns:s:Spark 组件库,现代 Flex 推荐使用的组件集合。xmlns:mx:旧版 Halo 组件库,主要用于兼容遗留系统。 阅读详情

作者 James Ward & Shashank Tiwari译者 韩锴  发布于 2008年3月6日 下午8时4分

社区 Java
主题 RIA,Web 2.0, Web框架
标签  Flex

 

简介

iPhone的成功明白无误地说明了一个事实:用户希望在他们的软件体验中感受到更多的交互。更多的交互可以让用户更好地利用程序的特性,提高他们的效率。这就是为什么“交互”不仅仅在个人信息管理程序中、而且在企业级业务程序中也是非常关键的。良好交互性的最大受益者是各种涉及到数据可视化的企业应用程序,因为更高的效率直接转化为了更好的决策,也立即会变为商业利润。 Dashboard是最典型的数据可视化应用程序。最具讽刺意味的是,今天大多数Dashboard在创建高效的用户体验的过程中,缺少交互性。因此我们决定一点点地美化一个典型的Web 1.0的Dashboard,给它增加更多的交互和丰富的功能。我们不会从头开始创建完整的应用程序,这未免是在重复发明车轮。相反,我们会重新设计界面,并把它整合到现有的服务器端架构中。通过这次学习,我们会完成一个简单但有意义的转 换。

 

我们在练习中使用的Dashboard是开源的Pentaho BI套件的一部分。数据和视图来自于Pentaho BI发行 版中的示例应用程序。

尽管我们的示例程序是一个Dashboard应用程序,但是其中的概念可以用于任何需要从Web 1.0迁移到 RIA的项目中。我们选用的RIA工具集是Adobe Flex。我们在此讨论的内容,全部是基于Flex框架、Flash VM以及相关支持库的。

如果你想亲自动手完成本文介绍的内容,应该安装下面的软件:


 

记住首先要启动Pentaho服务器、登录到Dashboard,然后才能运行Flex界面。Flex界面假设你已经登录并通过验证了。源代码还假设服务器会监听8080端口、等待HTTP请求。如果你的Pentaho HTTP服务器需要监听其他的端口,请修改源代码。为了方便那些希望跳过安装Pentaho服务器这步骤的人,下载的 Pentaho源代码绑定包中还包含一个伪数据集版本的Flex界面。

现在已经万事俱备了,下面可以仔细研究我们的示例程序了。

看看我的Pentaho Dashboard

首先是免责声明——这篇文章能够仅仅提供了一点浅尝辄止的体验。尽管不是必须的,不 过如果你希望在深入学习本文前先了解一些背景知识的话,可以到learn.adobe.com或者flex.org去看看。这篇文章也没有打算讲述创建可维护的代码构架的最佳 实践,或者用户界面的设计实践。比如,尽管使用Ely Greenfield的Chart drill down组件 [demo]可以改进用户体验,但是它 也会让你付出更多的努力才能设置并运行示例程序,因此我们在示例中并没有选用它。我们希望为那些只想简单了解一下代码的人,提供一种单纯的复制与粘贴的体验。如果混入了第三方的组件或者一个实实在在的MVC架构,将会令这个体验变得复杂。如果你想进一步深入挖掘这些主题,可以在网上或者Adobe Developer Connection上找到大量的相关文章。

为了让你能够对我们即将创建的东西有一个了解,我们先来看看最终 的效果。 查看Demo。

 

而Pentaho Dashboard最初的样子却是这样的:

正如前文提到的,我们使用Flex创建新的Dashboard。这个基于Flex的Dashboard是用声明式的MXML语言和过程式的ActionScript语言编写的,并利用免费的Flex SDK编译为SWF文件。SWF文件是Flash Player VM上的字节码。你可以在浏览器中运行SWF文件,或者通过Adobe整合运行时(AIR)将它转化为一个桌面应用程序。让我们先来看看创建新的Dashboard的源代码。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()" layout="horizontal">
<mx:Script>
<![CDATA[
// import classes used in ActionScript and not used in the MXML
// ActionScript is code generated from MXML by the free Flex SDK's mxmlc compiler
// The generated ActionScript can be viewed if you pass mxmlc the - compiler.keep-generated-actionscript argument
import mx.charts.HitData;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;

// Bindable is a metadata / annotation which generates event code so that the variable
// can be used in an MXML Binding Expression, ie. dataProvider="{territoryRevenue} "
[Bindable] public var territoryRevenue:ArrayCollection;
[Bindable] public var productlineRevenue:Object;
[Bindable] public var topTenCustomersRevenue:Object;

// Variables in ActionScript have namespaces like in Java. You can use the typical public,
// private, and protected namespaces as well as create your own namespaces
// Object types are specified with a colon character and are optional but recommended.
private var _selectedTerritory:String = "*";
private var _selectedProductLine:String = "*";

// the initApp function is called when the Application's creationComplete event is fired (see the mx:Application tag above
private function initApp():void
{
// initializes our data caches
productlineRevenue = new Object();
topTenCustomersRevenue = new Object();

// initiates the request to the server to get the Sales by Territory data
// tSrv is defined in MXML below. It could also have been defined in ActionScript but would have been slightly more verbose tSrv.send();

// Since the Sales by Product Line and Top Ten Customer Sales depend on the selected territory
// we make a call to the functions that will fetch the data based on the selected territory (or pull it from cache)
// in this case the selected territory is "*" or our indicator for all. When the users selects a new territory
// these methods will be called again but the selected territory will be different
updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

// Setter method that causes the data stores for the Sales by Product Line and Top Ten Customer Sales
// to be updated and the charts to be updated accordingly
public function set selectedTerritory (territory:String):void
{
// update the private backing variable
_selectedTerritory = territory;

updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

// Getter method that returns the selected Territory
// This method has the Bindable metadata / annotation on it so that the selectedTerritory property can
// be used in a binding expression
[Bindable] public function get selectedTerritory():String
{
return _selectedTerritory;
}

// Setter method similar to selectedTerritory but for the selected product line
public function set selectedProductLine(productLine:String):void
{
_selectedProductLine = productLine;

updateTopTenCustomersRevenue();
}

[Bindable] public function get selectedProductLine():String
{
return _selectedProductLine;
}

// If the data is in cache then just directly update the chart based on the selected territory.
// If the data is not in cache then assemble the name value pairs that are needed by the
// web service request, then make the request.
private function updateProductLineRevenue():void
{
if (productlineRevenue[_selectedTerritory] == undefined)
{
productlineRevenue [_selectedTerritory] = new ArrayCollection();

var p:Object = new Object();

if (_selectedTerritory != "*")
{
p.territory = _selectedTerritory;
}

plSrv.send(p);
}
else
{
plPie.dataProvider = productlineRevenue[_selectedTerritory];
}
}

// Similar to updateProductLineRevenue except that both the selected territory and
// the selected product line determine the data set.
private function updateTopTenCustomersRevenue():void
{
if (topTenCustomersRevenue [_selectedTerritory + '_' + _selectedProductLine] == undefined)
{
topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine] = new ArrayCollection();

var p:Object = new Object();

if (_selectedTerritory != "*")
{
p.territory = _selectedTerritory;
}

if (_selectedProductLine != "*")
{
p.productline = _selectedProductLine;
}

ttcSrv.send(p);
}
else
{
ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine];
}
}

// This function handles a response from the server to get the Sales by territory. It reorganizes that data
// into a format that the chart wants it in. The tPie chart notices changes to the underlying ArrayCollection
// that happen inside the for each loop. When it sees changes it updates it's view of the data.
private function handleTResult (event:ResultEvent):void
{
territoryRevenue = new ArrayCollection();
tPie.dataProvider = territoryRevenue;

var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-HDR-ROW']['COLUMN-HDR- ITEM'];
for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl ['DATA-ITEM'][1];
territoryRevenue.addItem(spl);
}
}

// Similar to handleTResult except that it handles the data for Sales by Product Line
private function handlePLResult(event:ResultEvent):void
{
var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN- HDR-ROW']['COLUMN-HDR-ITEM'];

for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl ['DATA-ITEM'][1];
productlineRevenue[_selectedTerritory].addItem(spl);
}

plPie.dataProvider = productlineRevenue[_selectedTerritory];
}

// Similar to handleTResult except that it handles the data for Top Ten Customer Sales
private function handleTTCResult(event:ResultEvent):void
{
var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['ROW-HDR- ROW'];
var pl:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'];

for (var i:int = 0; i < pl.length; i++)
{
var spl:Object = new Object();
spl.name = hdr[i]['ROW-HDR-ITEM'][0];
spl.sales = pl[i]['DATA-ITEM'];
topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine].addItemAt(spl,0);
}

ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine];
}

// This function is called to format the dataToolTips on the tPie chart.
private function formatTPieDataTip (hitdata:HitData):String
{
return "<b>" + hitdata.item.TERRITORY + "</b><br>" + cf.format(hitdata.item.SOLD_PRICE);
}
]] >
</mx:Script>

<!-- These HTTP Services communicate via HTTP to a server -->
<mx:HTTPService id="tSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel- wheels/homeDashboard&action=Sales_by_Territory.xaction" result="handleTResult (event)"/>
<mx:HTTPService id="plSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel- wheels/homeDashboard&action=Sales_by_Productline.xaction" result="handlePLResult(event)"/>
<mx:HTTPService id="ttcSrv" url="http://localhost:8080/pentaho/ServiceAction? solution=samples&path=steel-wheels/homeDashboard&action=topnmdxquery.xaction" result="handleTTCResult(event)"/>
<!-- Non-visual component to format currency's correctly. Used in the formatTPieDataTip function -->
<mx:CurrencyFormatter id="cf" precision="0"/>

<!-- Effects used to make the charts more interactive -->
<mx:SeriesInterpolate id="plEffect"/>
<mx:SeriesSlide id="ttcSlide" direction="right"/>

<!-- Stacked vertical layout container -- >
<mx:VBox height="100%" width="40%">
<!-- Nice box with optional drop shadows, title bars, and control bars -->
<mx:Panel width="100%" height="100%" title="Revenue By Territory">
<!-- Pie Chart -->
<mx:PieChart id="tPie" width="100%" height="100%" showDataTips="true" dataTipFunction="formatTPieDataTip">
<!-- Sets the itemClick property on the PieChart to the embedded ActionScript code. We could have also called a function defined above. -->
<mx:itemClick>
// calls the appropriate setter method
selectedTerritory = event.hitData.item.TERRITORY;

// tells the pie chart to explode the pie wedge the user click on
var explodeData:Array = [];
explodeData[territoryRevenue.getItemIndex(event.hitData.item)] = 0.15;
tPie.series [0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>
<!-- Sets the series property on the Pie Chart. -->
<mx:series>
<!-- The Pie Series defines how the Pie Chart displays it's data. -->
<mx:PieSeries nameField="TERRITORY" field="SOLD_PRICE" labelPosition="insideWithCallout" labelField="TERRITORY"/>
</mx:series>
</mx:PieChart>
</mx:Panel>

<!-- A Binding Expression in the title bar of the Panel uses the Bindable getter for the selectedTerritory property -->
<mx:Panel width="100%" height="100%" title="Revenue By Product Line (Territory = {selectedTerritory})">
<mx:PieChart id="plPie" width="100% " height="100%" showDataTips="true">
<mx:itemClick>
selectedProductLine = event.hitData.item.PRODUCTLINE;

var explodeData:Array = [];
explodeData[productlineRevenue [_selectedTerritory].getItemIndex(event.hitData.item)] = 0.15;
plPie.series [0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>
<mx:series>
<!-- The showDataEffect on the Series uses Binding to (re)use an effect defined above -->
<mx:PieSeries nameField="PRODUCTLINE" field="REVENUE" labelPosition="insideWithCallout" showDataEffect=" {plEffect}" labelField="PRODUCTLINE"/>
</mx:series>
</mx:PieChart>
</mx:Panel>
</mx:VBox>
<mx:Panel width="100%" height="100%" title="Top 10 Customers (Territory = {selectedTerritory} | Product Line = {selectedProductLine})">
<mx:BarChart id="ttcBar" width="100%" height="100%" showDataTips="true">
<mx:series>
<mx:BarSeries xField="sales" showDataEffect="{ttcSlide}"/>
</mx:series>
<mx:verticalAxis>
<mx:CategoryAxis categoryField="name"/>
</mx:verticalAxis>
</mx:BarChart>
</mx:Panel>

</mx:Application>

下载并查看源代码。注意应用程序有两个版本。一个是使用伪数据集的 pentaho_dashboard_demo.mxml,另一个是会连接到真实的Pentaho服务器以获取数据的 pentaho_dashboard.mxml。

迁移过程

向RIA迁移的过程的第一步是设计一个新界面。同时你还需要明确如何向应用程序暴露出数据和服务。 Pentaho已经为我们暴露出了数据和服务,所以留下来最难的部分是把数据解析为Flex Charting组件所期望的格式。最终你可以将后端的服务与新的界面挂接到一起。让我们来深入每一步的细节。

设计新的接口

创建新RIA接口的最佳思考方式是什么?不是考虑如何使现有的接口更丰富,而是要以用户希望如何查看以及与数据交互为出发点,重新进行思考。在这个过程中,设计师会发挥很大的作用。如果可能,尽可能地发挥他们的创造性。作为开发者,你可以先创建一个原型。为了提高效率,你需要创建一个模拟数据集。你可以在Sales_by_Productline.xaction、Sales_by_Territory.xaction和 topnmdxquery.xaction文 件中找到我们使用的数据集。在例子中,我把模拟数据集做成与Pentaho暴露出来的Web Services很相似 。尽管这不是必须的,但它简化了挂接到真正的服务上所需的工作。 有了模拟数据集,我们可以在设计 上进行更快的迭代了。

我们所做的设计看上去与原来的Dashboard几乎一样。如果有一位设计师帮助我们(实际上并没有),我们可以拿出更有创造性的产品。尽管如此,我们这些开发者还是能够创建出有更多交互的Dashboard。我们其实可以设计出更复杂的界面来,但是在这个例子中,还是希望保持代码易于阅读和理解。

创建UI的代码相当直接。下面的MXML代码就能创建一个PieChart:

<mx:PieChart width="100%" height="100%">
<mx:series>
<mx:PieSeries nameField="TERRITORY" field="SOLD_PRICE" labelPosition="insideWithCallout" labelField="TERRITORY"/>
</mx:series>
</mx:PieChart>

为了增加交互性,你可以添加一个itemClick事件处理器:

<mx:itemClick>
selectedTerritory = event.hitData.item.TERRITORY;

var explodeData:Array = [];
explodeData[territoryRevenue.getItemIndex (event.hitData.item)] = 0.15;
tPie.series[0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>

当我们设置selectedTerritory时(就像在itemClick事件处理器中所做的),会引起一些其他的动作 。这个例子中,我们希望刷新数据集,这个数据集与相应的饼图绑定到一起了:

public function set selectedTerritory(territory:String):void
{
_selectedTerritory = territory;

updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

我们也可以很简单地为数据集已改变的Chart增加一个平滑的转化。第一件要做到事情就是添加一个我 们打算使用的效果的实例

<mx:SeriesInterpolate id="plEffect"/>

我们还需要把showDataEffect绑定到效果的实例上,这样,当数据发生变化后,就可以通知饼状图使 用这个效果了

<mx:PieSeries nameField="PRODUCTLINE" field="REVENUE"   labelPosition="insideWithCallout" showDataEffect="{plEffect}"   labelField="PRODUCTLINE"/>

我们也可能想增加一个鼠标悬浮时的提示:

<mx:PieChart id="tPie" width="100%" height="100%"   showDataTips="true" dataTipFunction="formatTPieDataTip">

dataTipFunction被命名为formatTPieDataTip,后者返回一个自定义的字符串:

private function formatTPieDataTip(hitdata:HitData):String
{
return "<b>" + hitdata.item.TERRITORY + "<b><br>" + cf.format(hitdata.item.SOLD_PRICE);
}

我们可以指定很多其他的风格来自定义应用程序的感观(look and feel)。开发者可以将风格内联在 属性中,也可以定义在外部的CSS文件中。

暴露后端

使用Pentaho,我们可以很容易地发现Web Service并与之交互。Web Service给我们提供了用于 Dashboard的数据。可以返回按照区域分布的销售版图的URL是(在本地运行时): 这里。

有些URL会携带参数,来确定返回什么数据集。例如,“十大客户”的Web Service可以带 有两个参数,区域和产品类型,它们共同决定了应该返回哪些信息。

将前端挂接到后端

要想把前端挂接到后端,你首先要创建一个HTTPService(如果使用的是SOAP,则创建WebService):

<mx:HTTPService id="tSrv"   url="http://localhost:8080/pentaho/ServiceAction?solution=
samples&path=steel -wheels/homeDashboard&action=Sales_by_Territory.xaction"
result="handleTResult(event)"/>

result属性指定了响应从服务器返回后要执行的代码。在这个例子中,我们只要调用一个名为 handleTResult的方法,并传递一个Event类型的参数就可以了。这个方法负责把我们接收到的数据转换为 Charts所需的样式。无论我们在使用Charts还是其他诸如DataGrid之类的组件,都需要一些简单的处理。在这个例子中,我们要对数据做一些处理然后再把它交给Chart。

private function handleTResult(event:ResultEvent):void
{
territoryRevenue = new ArrayCollection();
tPie.dataProvider = territoryRevenue;

var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN- HDR-ROW']['COLUMN-HDR-ITEM'];

for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl['DATA-ITEM'][1];////////
territoryRevenue.addItem(spl);
}
}

在这个例子里,所有的代码都放到一个文件中了。在实际的项目中,我们会按照模型、视图和控制器的架构将它拆分到不同的文件中。我们在其他的时间里详细讨论如何使用正确的设计模式来构建大型的应用程序。至此,我们就完成了这个示范的应用程序。从现在开始到本文结束,我们将通过Adobe Flex讨论 RIA的一些有趣的方面。

这个示例的精彩之处为何?

这个简单的示例证明了对于传统的Web应用程序来说,丰富的、带有更多交互的用户界面是多么重要。这个程序的美妙之处,是它为现有的程序提供一个很棒的界面,却不需要进行大量的重构。这种便利一部分要归因于Pentaho暴露出了它的服务器端调用,另一部分归因于Flex能够平稳地消化掉这些服务的能力 ,这得利于Flex的组件和数据绑定模型。

这里示例同样示范了如何谨慎地选择、匹配各种技术。一个优秀的、健壮的Java服务器程序可以有效 地被挂接到一个富Flex界面,从而创造出令人眩目的程序。这是一个很有前景的方向,这个示例希望能将 这种理念带入现实。

应用程序的另一方面是,我们通过真实的、可运行的代码能够看到,使用ActionScript和MXML构建 Flex应用程序是多么容易。对于大多数熟悉Java和XML语法的人来说,ActionScript和MXML看起来是相当 亲切的。不是吗?

现在还差什么?如何弥补这一缺口?

这个示例并不是产品级的软件。它更关注于一个简单的原型。但是,如果花些时间将Pentaho Web Service调用抽象为一个ActionScript库,这可能是迈向健壮程序的第一步。有一些开源项目已经开始着手构建这样的库了。示例程序也在向这个方向靠拢,并且使用了很少的一些面向对象的构造。应用MVC架构模式,面向接口编程,恰当地使用继承和多态,就能创建出可维护的、干净的应用程序。在示例程序中,我们只是简单复制了旧程序的外观。在理想的情况下,我们应该根据交互性需求创建出全新的界面,然 后将可视化组件和Web Service组件绑定到一起。为了创建出满足生产环境要求的应用程序,我们应该投 入时间和精力。

进一步阅读

这个示例仅仅是富互联网应用程序的冰山一角。 比如我们可做的改进之一就是把图表做成可以逐层深 入(drill down)细节的,并加上更有意义的过渡效果。Ely Greenfield建了一个很漂亮的演示,他详细 说明了如何用Flex Charts实现drill down效果,请移步他的博客 。我们使用的是Flex 2构建示例程序,不过在Flex 3中,Chart 组件还包含了一些新的特性。你可以在这里或者这里读到更多的信息。如果你想学习Flex编程,可以查看 flex.org和learn.adobe.com 。

关于作者

James Ward是Adobe公司的Flex技术布道者,也是Adobe的JCP代表,负责JSR 286、299和301。就像他最爱的爬山一样,他也热爱编程,认为它提供了无穷尽的新发现。他在爬山的过程中到过很多地方。同样,技术也带给他很多冒险经历,其中包括:九十年代早期是pascal和汇编;九十年代中期是Perl、HTML和 JavaScript;Java及其大量框架都是始于九十年代后期。现在他的主要工作是利用Flex构建好看的前端,而后端还是基于Java。在来到Adobe之前,他曾经创建过一个服务门户。你可以在他的博客上了解更多信 息:www.jamesward.org。

Shashank Tiwari是Saven Technologies首席技术官。Saven Techologires位于芝加哥,为银行和金融服务公司提供服务。 Shashank是一位经验丰富的开发者、作家和演说家,在是JSR 274, 283, 299, 301和312专家组的成员。他对大量语言都感兴趣,包括Java、ActionScript、Ptyhon、Perl、PHP、G++、Groovy、JavaScript、 Ruby和Matlab。他也是OReilly网络的知名作者。最近他在忙于使用Flex和Java构建Web 2.0应用程序。更 多信息可以访问:www.shanky.org。

查看英文原文:From Tags to Riches: Going from Web 1.0 to Flex

PCIe扫盲(三) 需要特别注意的是,PCIe的Spec中明确规定只有Root有权限发起配置请求(Originate Configuration Requests),也就是说PCIe系统里面的其他设备是不允许去配置其他设备的配置空间的,即peer-to-peer的配置请求是不允许的。当配置请求进行BDF路由的时候,正是依靠这些信息来确定要找的设备的。前面的文章还介绍过,Root和Switch的每一个端口中都包含一个P2P桥,并且知道桥的配置空间头(Configuration Space Header)是Type1型的。 阅读详情

相关推荐

FFmpeg音频转换避坑实录:为什么VOS的REC转MP3比WAV转MP3体积小一半?

本文深入解析了FFmpeg在VOS系统REC格式音频转换中的优化技巧,揭示了REC转MP3比WAV转MP3体积小一半的原因。通过分析REC格式的压缩特性、转码参数陷阱及FFmpeg调优方法,帮助开发者实现高效音频转换,显著降低存储成本。

weixin_30752699的博客 527

从客户端检测到有潜在危险的Request.Form 值

提交查询时,报错显示"从客户端检测到有潜在危险的Request.Form 值"(.Net Framework1.1)的解决方案:1、web.config文件后面加入这一句:          示例:             2、在*.aspx文件头的Page中加入validateRequest="false",示例如下: 

千里之行 2313

别再傻傻分不清了!Anaconda和Miniconda到底选哪个?附保姆级安装与镜像源配置(Windows/Mac)

本文详细解析了Anaconda和Miniconda的核心差异,包括体积、预装内容、系统资源占用等关键维度,并提供了针对不同需求的决策框架。附有Windows和Mac双平台的详细安装与配置指南,帮助用户根据实际需求选择最适合的conda工具,提升开发效率。

weixin_30315723的博客 426

kindeditor在asp.net使用时,出现“从客户端中检测到有潜在危险的 Request.Form 值 ”问题。...

今天在使用Kindeditor的时候,出现了如题的错误。错误如图:   百度了下,艰难的找了原来是Framework的问题,原来用的2.0,后面变成了4.0,验证级别也更高了;解决办法:在config文件中加一句:&lt;httpRuntime requestValidationMode="2.0" /&gt;,意思就是启用2.0的验证;添加完就解决了。 代码: &lt;?xml ...

weixin_34419321的博客 174

如何用Deep OC-SORT提升多目标跟踪精度?实战配置与性能优化指南

本文是一份针对开发者的Deep OC-SORT多目标跟踪实战指南。详细解析了如何通过部署其核心的“动态外观记忆”与“相机防抖”模块来有效应对遮挡与抖动,从而显著提升跟踪精度与连续性。内容涵盖从环境搭建、参数调优到性能压榨的全流程,并提供针对不同场景的配置建议与工程落地技巧。

f9g0h的博客 670

UE5游戏逆向实战:用FModel提取.pak文件中的3D模型(附Dumper-7避坑指南)

本文详细介绍了如何使用FModel工具从UE5游戏的.pak文件中提取3D模型,并提供了Dumper-7的避坑指南。内容涵盖FModel工具链配置、UE5特有的unversioned properties问题解决方案、Dumper-7实战流程以及模型后处理技巧,帮助开发者高效获取游戏资产。

weixin_30872499的博客 422

flex 百科简介

flex通常是指Adobe Flex,是最初由Macromedia公司在2004年3月发布的,基于其专有的Macromedia Flash平台,它是涵盖了支持RIA(Rich Internet Applications)的开发和部署的一系列技术组合。flex的另一个意思是一款生成扫描器的工具,能够识别文本中的词法模式。 简介 Flex 是一个高效、免费的开源框架,...

anchang7456的博客 1242

测试丢包_电信IPRAN承载LTE业务丢包故障处理案例

银川 景旭阳电信IPRAN承载LTE业务丢包故障处理案例一.故障现象某地市IPRAN网络承载LTE基站业务,客户反馈近期丢包严重,基站侧ping侧核心网EPC丢包达到10%左右;且基站数量在10个左右,并分布在同一地区,需要IPRAN网络协助排查;随后查看了IPRAN网络;发现这些业务所在基站的PW-BFD历史告警存在频繁的UP/DOWN告警;综上信息展开故障处理,初步判断由于BFD频繁...

weixin_29740921的博客 1912

Interesting Finds: 2008.03.09

Web: 从标签时代到富客户端:从Web 1.0到Flex jQuery Tutorials for Designers IE8 Beta 1的AJAX支持以及跨域新功能 .NET: Web Based MP3 Player & CMS ASP.NET AJAX In-Depth: Application Events ILVisualizer VS2008 solution...

weixin_30678349的博客 75

AIGC算法工程师-面试八股文-2025年版本-算法八股文/工程八股文/开放式问题

​两年前整理了《AIGC算法工程师 面试八股文》,全网一共有100w读者看过,收到了很多小伙伴的催更。Diffusion的技术发展非常快,博主特意整理了最近两年最新的八股文,内容非常全面,涵盖算法八股文/工程八股文/开放式问题三个大类,希望能为求职的读者们带来帮助。

沉迷单车的追风少年 4186

【Unity的HDRP渲染管线下用Steam VR串流结合使用遇到的各种问题_SteamVR 插件和Pico串流助手】

当你启用"Mock Runtime"选项后,Unity将模拟一个虚拟的OpenXR运行时环境,并提供一些虚拟的设备和功能,让你能够进行开发和调试。在Unity中,SteamVR插件是一个由Valve提供的Unity插件,它允许开发者在Unity项目中集成SteamVR功能,以便支持SteamVR设备。OpenXR是一个跨平台的虚拟和增强现实(VR/AR)开发接口,它为开发者提供了一个统一的接口,用于访问不同VR/AR硬件设备和平台的功能。这个选项是用于模拟OpenXR运行时环境的功能。

暴走约伯的博客 2800

[转]Flex是什么?flex和flash是什么关系 ?

Flex是Macromedia发布的presentation server(展现服务),它是java web container或者.net server的一个应用,根据.mxml文件(纯粹的xml描述文件和actionscript)产生相应得.swf文件,传送到客户端,由客户端的 flash player或者shockwave player解释执行,给用户以丰富的客户体验。   大名...

weixin_30409849的博客 74

HQChart实战教程19 - PC端分时图定制tooltip

HQChart实战教程19 - PC端分时图定制tooltip序效果步骤1. 创建一个外部tooltip的div2. 注册标题绘制事件3. 标题绘制回调函数格式说明eventdataobjtooltip显示函数HQChart代码地址 序 hqchart分时图是不带tooltip, 如果我们需要在PC端页面显示tooltip,我们可以通过注册绘制标题事件,来自己做一个div显示数据。 参考教程HQChart实战教程7-自定义显示手势点击K线显示信息 效果 步骤 1. 创建一个外部tooltip的div 在外

小银 2447

Adobe Flex

简介   Flex 是一个高效、免费的开放源框架,可用于构建具有表现力的 Web 应用程序,这些应用程序利用 Adobe&reg; Flash&reg; Player 和 Adobe AIR&reg; 运行时跨浏览器、桌面和操作系统实现一致的部署。虽然只能使用 Flex 框架构建 Flex 应用程序,Adobe Flash Builder™(之前称为...

weixin_33851604的博客 148

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

flex是什么

Flex是Macromedia发布的presentation server(展现服务),它是java webcontainer或者.netserver的一个应用,根据.mxml文件(纯粹的xml描述文件和actionscript)产生相应得.swf文件,传送到客户端,由客户端的flash player或者shockwave player解释执行,给用户以丰富的客户体验。  大名

yingying0708的专栏 1206

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

V1封装专项总结:从PCB封装库到软件接口层的实战经验

封装是硬件设计与软件开发中降低复杂度、沉淀稳定的关键技术手段。在硬件领域,统一元器件封装库与命名规范直接决定PCB的可靠性与可制造性;在软件领域,将请求层、流式输出与多环境配置进行统一封装,可显著减少重复代码与联调成本。本文结合V1封装专项实践,系统讲解了公制与英制尺寸识别、AD与Allegro封装制作流程、焊盘编号批量修正等硬件方法,以及axios二次封装、SSE流式输出、多域名动态配置等软件方案,并对常见问题给出排查清单。无论你是PCB工程师还是前端开发者,都能从中找到可落地的封装思路。

weixin_34396902的博客 377

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Flex学习手册新手必备

本文和大家重点讨论一下Flex学习手册,Flex是一个提供开发设计和运行支持的架构,它可以使开发人员创建利用Adobe?Flash?Player9作为前台的“富客户端互联网应用程序/richInternetapplications/RIA”,以满足用户更为直观和极具交互性的在线体

bearhoop IT之道 1251

Flex 入门介绍

一、Flex 介绍 Flex 是一个高效、免费的开源框架,可用于构建具有表现力的 Web应用程序,这些应用程序利用Adobe Flash Player和Adobe AIR, 可以实现跨浏览器、桌面和操作系统。虽然只能使用 Flex 框架构建 Flex应用程序,但Adobe Flash Builder™(之前称为 Adobe Flex Builder™)软件可以通过智能编码、交互式遍历调试以及可...

267

第一篇 敲开FLEX的大门

 第一篇        敲开FLEX的大门WEB2.0的时代是一个概念已经被过度泛滥的时代.身为程序员的我们何尝不是一个个孤独的剑客泛舟在波涛汹涌的概念海洋里, 被风雨不断地吹打,磨砺,淘汰和新生。身为剑客,我们一直在为命运杀戮. 所谓的武功秘籍到处都是。 狠心花点银子买来一本,在不为人知的山谷中苦练时日,以便重出江湖,成为令狐冲,张无忌,杨过,又或者是另一个东方不败! 他们的腰里都别着不

Flex技术专栏 --by mervyn_lee 6143

构建Flex应用的10大误区

构建Flex应用的10大误区作者 Jon Rose译者 张龙 发布于 2008年4月25日 上午10时7分 社区Java主题Web框架,Web 2.0,RIA,富客户端/桌面标签Adobe,Adobe集成运行时/AIR,Flex,Flash,Apollo在这篇新闻中,Adobe的James Ward与InfoQ.com一起为你带来了Flex的另一种10大(Flex最新的10大)。Fle

phdbrianlee的专栏 497

Flex简介

Adobe Flex 简介   Flex 是一个高效、免费的开放源框架,可用于构建具有表现力的 Web 应用程序,这些应用程序利用 Adobe&reg; Flash&reg; Player 和 Adobe AIR&reg; 运行时跨浏览器、桌面和操作系统实现一致的部署。虽然只能使用 Flex 框架构建 Flex 应用程序,Adobe Fl...

weixin_34195364的博客 177

flex

百科名片flex通常是指Adobe Flex,是最初由Macromedia公司在2004年3月发布的,基于其专有的Macromedia Flash平台,它是涵盖了支持RIA(Rich Internet Applications)的开发和部署的一系列技术组合。flex的另一个意思是是一款生成扫描器的工具,能够识别文本中的词法模式。 Adobe Flex简介Macromedia

628

flex系列文章:第一章. Flex概念和工具初步

第一章. Flex概念和工具初步 1.1 RIA(Rich Internet Application)  我们已经非常熟悉当前标准的WEB应用的触发方式, 客户端请求服务,服务端同步地响应请求并刷新客户端IE.这是一种标准的瘦客户胖服务端的概念.RIA的概念正好相反,RIA应用运行在传统标准的IE上,但是它建立了一套独立于标准Client/Server请求响应模式.请求发出后,客户

elimago的专栏 2465

Flex

Flex 2011年07月11日   flex通常是指Adobe Flex,是最初由Macromedia公司在2004年3月发布的,基于其专有的Macromedia Flash平台,它是涵盖了支持RIA(Rich Internet Applications)的开发和部署的一系列技术组合。flex的另一个意思是是一款生成扫描器的工具,能够识别文本中的词法模式。   Adobe Flex...

mar88mar 190
上一篇: JavaFX技术预览
下一篇: 使用Grails和Flex开发JEE应用
taoff
博客等级 码龄23年 2粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值