Silverlight技术调查(4)——完成的调查结果
原文 Silverlight技术调查(4)——完成的调查结果
客户端使用Silverlight+DXperience,可以在线编辑各种常见文本及富文本文档(doc、docx、rtf、txt、html……),Silverlight使用了异步提交和响应(通过WebClient和WebRequest),提交时,自行编排HTTP请求格式(请参见相应RFC标准);编辑的数据流上传至Servlet后,Servlet使用commons-fileupload-1.2.2解包数据,获取附加的请求参数及附件内容。
程序效果:
下面为客户端和服务器端程序:
(一)客户端Silverlight由部分组成:
1、主程序画面Layout部分MainPage.xaml:
- <UserControl x:Class="RichEdit.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- d:DesignHeight="300" d:DesignWidth="400" xmlns:dxre="http://schemas.devexpress.com/winfx/2008/xaml/richedit" xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon">
- <UserControl.Resources>
- <ResourceDictionary>
- <dxre:RichEditUICommand x:Key="commands" />
- <dxre:RichEditStringIdConverter x:Key="stringIdConverter" />
- </ResourceDictionary>
- </UserControl.Resources>
- <Grid x:Name="LayoutRoot" Background="White">
- <dxb:BarManager Name="barManager1" ToolbarGlyphSize="Small">
- <dxb:BarManager.Items>
- <dxb:BarButtonItem Command="{Binding Path=FileNew, Mode=OneTime, Source={StaticResource commands}}" Name="biFileNew" />
- <dxb:BarButtonItem Command="{Binding Path=FileSaveAs, Mode=OneTime, Source={StaticResource commands}}" Name="biFileSaveAs" />
- <dxb:BarButtonItem Command="{Binding Path=FilePrint, Mode=OneTime, Source={StaticResource commands}}" Name="biFilePrint" />
- <dxb:BarButtonItem Command="{Binding Path=FilePrintPreview, Mode=OneTime, Source={StaticResource commands}}" Name="biFilePrintPreview" />
- <dxb:BarButtonItem Command="{Binding Path=FileBrowserPrint, Mode=OneTime, Source={StaticResource commands}}" Name="biFileBrowserPrint" />
- <dxb:BarButtonItem Command="{Binding Path=FileBrowserPrintPreview, Mode=OneTime, Source={StaticResource commands}}" Name="biFileBrowserPrintPreview" />
- <dxb:BarButtonItem Command="{Binding Path=EditUndo, Mode=OneTime, Source={StaticResource commands}}" Name="biEditUndo" />
- <dxb:BarButtonItem Command="{Binding Path=EditRedo, Mode=OneTime, Source={StaticResource commands}}" Name="biEditRedo" />
- <dxb:BarButtonItem Content="LoadFromWeb" Name="barButtonItemLoad" Glyph="/RichEdit;component/Images/Chrysanthemum.jpg" ItemClick="barButtonItemLoad_ItemClick" GlyphAlignment="Top" GlyphSize="Default" />
- <dxb:BarButtonItem Name="barButtonItemSave" Glyph="/RichEdit;component/Images/Desert.jpg" Content="SaveToWeb" ItemClick="barButtonItemSave_ItemClick" />
- <dxb:BarStaticItem Content="message..." Name="barStaticItemMsg" />
- </dxb:BarManager.Items>
- <dx:DockPanel>
- <dxr:RibbonControl dx:DockPanel.Dock="Top" Name="ribbonControl1">
- <dxr:RibbonControl.ApplicationMenu>
- <dxr:ApplicationMenuInfo />
- </dxr:RibbonControl.ApplicationMenu>
- <dxr:RibbonDefaultPageCategory>
- <dxr:RibbonPage Caption="{Binding Source={StaticResource stringIdConverter}, ConverterParameter=Caption_PageFile, Converter={StaticResource stringIdConverter}, Mode=OneTime}" Name="pageFile">
- <dxr:RibbonPageGroup Caption="{Binding Source={StaticResource stringIdConverter}, ConverterParameter=Caption_GroupCommon, Converter={StaticResource stringIdConverter}, Mode=OneTime}" Name="grpCommon" ShowCaptionButton="False">
- <dxb:BarButtonItemLink BarItemName="biFileNew" />
- <dxb:BarButtonItemLink BarItemName="biFileSaveAs" />
- <dxb:BarButtonItemLink BarItemName="biFilePrint" />
- <dxb:BarButtonItemLink BarItemName="biFilePrintPreview" />
- <dxb:BarButtonItemLink BarItemName="biFileBrowserPrint" />
- <dxb:BarButtonItemLink BarItemName="biFileBrowserPrintPreview" />
- <dxb:BarButtonItemLink BarItemName="biEditUndo" />
- <dxb:BarButtonItemLink BarItemName="biEditRedo" />
- </dxr:RibbonPageGroup>
- <dxr:RibbonPageGroup Caption="Ribbon Page Group 1" Name="ribbonPageGroup1">
- <dxb:BarButtonItemLink BarItemName="barButtonItemLoad" />
- <dxb:BarButtonItemLink BarItemName="barButtonItemSave" />
- </dxr:RibbonPageGroup>
- <dxr:RibbonPageGroup Caption="Ribbon Page Group 2" Name="ribbonPageGroup2">
- <dxb:BarStaticItemLink BarItemName="barStaticItemMsg" />
- </dxr:RibbonPageGroup>
- </dxr:RibbonPage>
- </dxr:RibbonDefaultPageCategory>
- </dxr:RibbonControl>
- <dxre:RichEditControl Name="richEditControl1" BarManager="{Binding ElementName=barManager1, Mode=OneTime}" Ribbon="{Binding ElementName=ribbonControl1, Mode=OneTime}" />
- </dx:DockPanel>
- </dxb:BarManager>
- </Grid>
- </UserControl>
2、主程序逻辑部分MainPage.xaml.cs:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using System.IO;
- using DevExpress.XtraRichEdit;
- using System.Threading;
- namespace RichEdit
- {
- public partial class MainPage : UserControl
- {
- public MainPage()
- {
- InitializeComponent();
- }
- String uri = "http://localhost:8888/upload/UploadServlet";
- private void barButtonItemLoad_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
- {
- MessageBox.Show("Load Begin");
- ServerStreamLoad ssl = new ServerStreamLoad();
- ssl.Rp = new ShowLoadResultDelegate(ShowLoadResult);
- ssl.Load(uri);
- }
- private void barButtonItemSave_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
- {
- MessageBox.Show("Save Begin");
- WebRequest request = WebRequest.Create(new Uri(uri));
- Dictionary<String, String> nvc = new Dictionary<String, String>();
- nvc.Add("name", "value");
- nvc.Add("name1", "value1");
- ServerStreamSave sss = new ServerStreamSave();
- sss.Rp = new ShowSaveResultDelegate(ShowSaveResult);
- Stream stream = new MemoryStream();
- this.richEditControl1.SaveDocument(stream, DocumentFormat.Rtf);
- sss.Save(request, nvc, stream);
- }
- // 处理Load结果
- public void ShowLoadResult(Stream stream)
- {
- String msg = "OK";
- if (this.barStaticItemMsg.CheckAccess())
- {
- this.barStaticItemMsg.Content = msg;
- }
- else
- {
- Dispatcher.BeginInvoke(() =>
- {
- this.barStaticItemMsg.Content = msg;
- });
- }
- using (stream)
- {
- if (this.richEditControl1.CheckAccess())
- {
- this.richEditControl1.LoadDocument(stream, DocumentFormat.Rtf);
- }
- else
- {
- Dispatcher.BeginInvoke(() =>
- {
- this.richEditControl1.LoadDocument(stream, DocumentFormat.Rtf);
- });
- }
- }
- }
- // 处理Save结果
- public void ShowSaveResult(String msg)
- {
- if (this.barStaticItemMsg.CheckAccess())
- {
- this.barStaticItemMsg.Content = msg;
- }
- else
- {
- Dispatcher.BeginInvoke(() =>
- {
- this.barStaticItemMsg.Content = msg;
- });
- }
- }
- }
- // 处理结果的委托
- public delegate void ShowLoadResultDelegate(Stream stream);
- public delegate void ShowSaveResultDelegate(String s);
- }
3、数据流异步下载部分ServerStreamLoad.cs:
- using System;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Ink;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using System.IO;
- namespace RichEdit
- {
- public class ServerStreamLoad
- {
- ShowLoadResultDelegate rp;
- public ShowLoadResultDelegate Rp
- {
- get { return rp; }
- set { rp = value; }
- }
- public void Load(String uri)
- {
- WebClient webClient = new WebClient();
- webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(LoadCompletedCallBack);
- webClient.OpenReadAsync(new Uri(uri));
- }
- private void LoadCompletedCallBack(object sender, OpenReadCompletedEventArgs e)
- {
- using (Stream stream = e.Result)
- {
- // read stream here
- rp(stream);
- }
- }
- }
- }
4、数据流异步提交部分:
- using System;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Ink;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using System.IO;
- using System.Collections.Generic;
- using System.Windows.Threading;
- namespace RichEdit
- {
- public class ServerStreamSave
- {
- static ShowSaveResultDelegate rp;
- public ShowSaveResultDelegate Rp
- {
- get { return rp; }
- set { rp = value; }
- }
- public void Save(WebRequest request, Dictionary<String, String> nvc, Stream stream)
- {
- request.Method = "POST";
- UploadState us = new UploadState();
- us.Req = request;
- us.Nvc = nvc;
- us.Stream = stream;
- request.BeginGetRequestStream(new AsyncCallback(SaveRequestReadyCallBack), us);
- }
- private void SaveRequestReadyCallBack(IAsyncResult asyncResult)
- {
- string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
- byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
- WebRequest request = ((UploadState)(asyncResult.AsyncState)).Req as WebRequest;
- request.ContentType = "multipart/form-data; boundary=" + boundary;
- request.UseDefaultCredentials = true;
- Stream rs = request.EndGetRequestStream(asyncResult);
- // 1.write boundery and key-value pairs
- string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
- IDictionary<String, String> nvc = ((UploadState)(asyncResult.AsyncState)).Nvc as IDictionary<String, String>;
- foreach (string key in nvc.Keys)
- {
- rs.Write(boundarybytes, 0, boundarybytes.Length);
- string formitem = string.Format(formdataTemplate, key, nvc[key]);
- byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
- rs.Write(formitembytes, 0, formitembytes.Length);
- }
- rs.Write(boundarybytes, 0, boundarybytes.Length);
- // 2.write head
- string file = "file";
- string paramName = "file";
- string contentType = "unknown";
- string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
- string header = string.Format(headerTemplate, paramName, file, contentType);
- byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
- rs.Write(headerbytes, 0, headerbytes.Length);
- // 3.write stream here,the stream will be closed by invoker
- using (Stream stream = ((UploadState)(asyncResult.AsyncState)).Stream as Stream)
- {
- stream.Position = 0;
- //byte[] buffer = System.Text.Encoding.UTF8.GetBytes("aaa我11");
- byte[] data = new byte[4096];
- int count = stream.Read(data, 0, 4096);
- while (count > 0)
- {
- rs.Write(data, 0, count);
- count = stream.Read(data, 0, 4096);
- }
- }
- //rs.Write(buffer, 0, buffer.Length);
- // 4.write trailer
- byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
- rs.Write(trailer, 0, trailer.Length);
- rs.Flush();
- rs.Close();
- request.BeginGetResponse(new AsyncCallback(SaveResponseReadyCallBack), request);
- }
- private void SaveResponseReadyCallBack(IAsyncResult asyncResult)
- {
- WebRequest request = asyncResult.AsyncState as WebRequest;
- WebResponse response = request.EndGetResponse(asyncResult);
- using (Stream responseStream = response.GetResponseStream())
- {
- StreamReader reader = new StreamReader(responseStream);
- // check response result by return msg.
- String msg = reader.ReadToEnd();
- rp(msg);
- }
- }
- }
- }
5、异步请求提交,回调封装参数部分UploadState.cs:
- using System;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Ink;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- namespace RichEdit
- {
- public class UploadState
- {
- IDictionary<String, String> nvc = null;
- public IDictionary<String, String> Nvc
- {
- get { return nvc; }
- set { nvc = value; }
- }
- WebRequest req = null;
- public WebRequest Req
- {
- get { return req; }
- set { req = value; }
- }
- Stream stream;
- public Stream Stream
- {
- get { return stream; }
- set { stream = value; }
- }
- }
- }
(二)服务器端使用commons-fileupload-1.2.2.jar实现上传:
1、web.xml配置:
- <servlet>
- <display-name>UploadServlet</display-name>
- <servlet-name>UploadServlet</servlet-name>
- <servlet-class>com.liyj.upload.servlet.UploadServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>UploadServlet</servlet-name>
- <url-pattern>/UploadServlet</url-pattern>
- </servlet-mapping>
2、UploadServlet.java(取打包的参数和附件)
- package com.liyj.upload.servlet;
- import java.io.*;
- import java.util.List;
- import javax.servlet.*;
- import javax.servlet.http.*;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- public class UploadServlet extends HttpServlet {
- public void init(ServletConfig config) throws ServletException {
- super.init(config);
- }
- public void doGet(HttpServletRequest request, HttpServletResponse response) {
- ServletOutputStream out = null;
- System.out.println("into doGet..");
- try {
- out = response.getOutputStream();
- FileInputStream fis = new FileInputStream("D:\\file");
- byte[] data = new byte[4096];
- int count = fis.read(data);
- while(count > 0) {
- out.write(data, 0, count);
- count = fis.read(data);
- }
- fis.close();
- out.flush();
- out.close();
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response) {
- ServletOutputStream out = null;
- System.out.println("into doPost..");
- DiskFileItemFactory factory = new DiskFileItemFactory();
- String path = "D:\\";
- factory.setRepository(new File(path));
- factory.setSizeThreshold(1024 * 1024);
- ServletFileUpload upload = new ServletFileUpload(factory);
- try {
- out = response.getOutputStream();
- List<FileItem> list = upload.parseRequest(request);
- for (FileItem item : list) {
- if (item.isFormField()) {
- String name = item.getFieldName();
- String value = item.getString("gbk");
- out.println(name + ":" + value);
- } else {
- String name = item.getFieldName();
- String value = item.getName();
- int start = value.lastIndexOf("\\");
- String fileName = value.substring(start + 1);
- //request.setAttribute(name, fileName);
- OutputStream os = new FileOutputStream(new File(path, fileName));
- InputStream is = item.getInputStream();
- byte[] buffer = new byte[1024];
- int length = 0;
- int fileLen = 0;
- while ((length = is.read(buffer)) > 0) {
- os.write(buffer, 0, length);
- fileLen += length;
- }
- out.println("OK");
- os.close();
- is.close();
- }
- }
- } catch (Exception e) {
- try {
- out.println("NG");
- } catch (IOException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- e.printStackTrace();
- }
- }
- }
---------- THE END-----------
Silverlight技术调查(4)——完成的调查结果的更多相关文章
- Silverlight技术调查(3)——国际化
原文 Silverlight技术调查(3)——国际化 网上有很多关于Silverlight国际化的说明,包括MSDN的示例,都没有强调一点,下面以红色标示,基础国际化知识请先参考MSDN相关章节,关键 ...
- Silverlight技术调查(2)——跨域访问
原文 Silverlight技术调查(2)——跨域访问 此调查web容器采用的是Tomcat,若允许所有域访问,只需在webapps下的根应用ROOT中,加入配置文件:clientaccesspoli ...
- Silverlight技术调查(1)——Html向Silverlight传参
原文 Silverlight技术调查(1)——Html向Silverlight传参 近几日项目研究一个很牛的富文档编辑器DXperience RichEdit组件,调查环境为Silverlight4. ...
- Python技术调查
1. IDE 2. Local Debugging & Remote Debugging 3. Profiling
- .NET Web开发技术简单整理
在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...
- CTO和技术副总裁应该如何分工?谁才是技术领导者?
谁是初创公司的技术领导者,是CTO还是技术副总裁?任何在创业公司工作的人都知道,我们不应该去问这个问题.因为这两个是非常不同的角色,角色本身会随着创业公司的发展而变化,两者对于业务规模都很重要. 简单 ...
- 使用SilverLight开发区域地图分析模块
本人最近接收开发一个代码模块,功能主要是在页面上显示安徽省市地图,并且在鼠标移动到地图某市区域时,显示当前区域的各类信息等,一开始准备用百度地图,高德地图等地图工具进行开发,最后发现都不适合进行此类开 ...
- Silverlight开发工具汇总
随着Silverlight技术的逐步完善,Silverlight应用大批的涌现,近期的2010年冬季奥运会,Silverlight作为首选视频播放技术,为全球提供在线赛事实况. Silverlight ...
- 转载:.NET Web开发技术简单整理
在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...
随机推荐
- Swift - 1 (常量、变量、字符串、数组、字典、元组、循环、枚举、函数)
Swift 中导入类库使用import,不再使用<>,导入自定义不再使用"" import Foundation 1> 声明变量和常量 在Swift中使用 &qu ...
- 队列的定义与实现(C语言实现)
小时候.我们做早操的时候或者军训的时候,都排成一列,有头有尾.如果你迟到了,仅仅能站到最后面一个.退场的时候.都是由第一个先走的.这就是队列雏形. 队列的定义 队列是一种特殊的线性表 队列仅在线性表的 ...
- ThinkPHP - 每个操作都检测用户是否登录
TP提供了一个自动执行的函数_initialize(), 你创建一个公共控制器CommonAction.class.php文件. 定义了此方法,不能存在构造方法__construct() <?p ...
- iOS 判断有无网络连接
众所周知,我们在开发APP时,涉及网络连接的时候,都会想着提前判断一下当前的网络连接状态,如果没有网络,就不再请求url,省去不必要的步骤,所以,这个如何判断?其实很简单. 前提:工程添加:Syste ...
- F - Free DIY Tour(动态规划,搜索也行)
这道题可用动态规划也可以用搜索,下面都写一下 Description Weiwei is a software engineer of ShiningSoft. He has just excelle ...
- instanceof 变量是否属于某一类 class 的实例
<?phpclass MyClass{} class NotMyClass{}$a = new MyClass;$b = new NotMyClass;var_dump($a instanceo ...
- 我的Python成长之路---第三天---Python基础(9)---2016年1月16日(雾霾)
一.集合 set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key. 集合和我们数学中集合的概念是一样的,也有交集,并集,差集,对称差集等 ...
- ZOJ 3329 One Person Game 【概率DP,求期望】
题意:有三个骰子,分别有k1,k2,k3个面. 每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和. 当分数大于n时结束.求游戏的期望步数.初始分数为0 设dp[i]表示达到 ...
- Uniconnection 连 mysql 有时会断线的
你定义localfailover:=ture.断线后会自己接上 firedac没这种功能.只有unidac有
- PHP脚本实现凯撒加(解)密
原文:PHP脚本实现凯撒加(解)密 今天在看某ctf时候遇到一题凯撒加密的题,然后看到write up里有这样一句 顿时感觉这题目有点坑啊,这要不写个脚本来跑要推到啥时候啊,于是又了本文: <? ...