Silverlight技术调查(4)——完成的调查结果

原文 Silverlight技术调查(4)——完成的调查结果

客户端使用Silverlight+DXperience,可以在线编辑各种常见文本及富文本文档(doc、docx、rtf、txt、html……),Silverlight使用了异步提交和响应(通过WebClient和WebRequest),提交时,自行编排HTTP请求格式(请参见相应RFC标准);编辑的数据流上传至Servlet后,Servlet使用commons-fileupload-1.2.2解包数据,获取附加的请求参数及附件内容。

程序效果:

Silverlight技术调查(4)——完成的调查结果

下面为客户端和服务器端程序:

(一)客户端Silverlight由部分组成:

1、主程序画面Layout部分MainPage.xaml:

 

[html] view plaincopy
 
  1. <UserControl x:Class="RichEdit.MainPage"  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.     mc:Ignorable="d"  
  7.     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">  
  8.     <UserControl.Resources>  
  9.         <ResourceDictionary>  
  10.             <dxre:RichEditUICommand x:Key="commands" />  
  11.             <dxre:RichEditStringIdConverter x:Key="stringIdConverter" />  
  12.         </ResourceDictionary>  
  13.     </UserControl.Resources>  
  14.     <Grid x:Name="LayoutRoot" Background="White">  
  15.         <dxb:BarManager Name="barManager1" ToolbarGlyphSize="Small">  
  16.             <dxb:BarManager.Items>  
  17.                 <dxb:BarButtonItem Command="{Binding Path=FileNew, Mode=OneTime, Source={StaticResource commands}}" Name="biFileNew" />  
  18.                 <dxb:BarButtonItem Command="{Binding Path=FileSaveAs, Mode=OneTime, Source={StaticResource commands}}" Name="biFileSaveAs" />  
  19.                 <dxb:BarButtonItem Command="{Binding Path=FilePrint, Mode=OneTime, Source={StaticResource commands}}" Name="biFilePrint" />  
  20.                 <dxb:BarButtonItem Command="{Binding Path=FilePrintPreview, Mode=OneTime, Source={StaticResource commands}}" Name="biFilePrintPreview" />  
  21.                 <dxb:BarButtonItem Command="{Binding Path=FileBrowserPrint, Mode=OneTime, Source={StaticResource commands}}" Name="biFileBrowserPrint" />  
  22.                 <dxb:BarButtonItem Command="{Binding Path=FileBrowserPrintPreview, Mode=OneTime, Source={StaticResource commands}}" Name="biFileBrowserPrintPreview" />  
  23.                 <dxb:BarButtonItem Command="{Binding Path=EditUndo, Mode=OneTime, Source={StaticResource commands}}" Name="biEditUndo" />  
  24.                 <dxb:BarButtonItem Command="{Binding Path=EditRedo, Mode=OneTime, Source={StaticResource commands}}" Name="biEditRedo" />  
  25.                 <dxb:BarButtonItem Content="LoadFromWeb" Name="barButtonItemLoad" Glyph="/RichEdit;component/Images/Chrysanthemum.jpg" ItemClick="barButtonItemLoad_ItemClick" GlyphAlignment="Top" GlyphSize="Default" />  
  26.                 <dxb:BarButtonItem Name="barButtonItemSave" Glyph="/RichEdit;component/Images/Desert.jpg" Content="SaveToWeb" ItemClick="barButtonItemSave_ItemClick" />  
  27.                 <dxb:BarStaticItem Content="message..." Name="barStaticItemMsg" />  
  28.             </dxb:BarManager.Items>  
  29.             <dx:DockPanel>  
  30.                 <dxr:RibbonControl dx:DockPanel.Dock="Top" Name="ribbonControl1">  
  31.                     <dxr:RibbonControl.ApplicationMenu>  
  32.                         <dxr:ApplicationMenuInfo />  
  33.                     </dxr:RibbonControl.ApplicationMenu>  
  34.                     <dxr:RibbonDefaultPageCategory>  
  35.                         <dxr:RibbonPage Caption="{Binding Source={StaticResource stringIdConverter}, ConverterParameter=Caption_PageFile, Converter={StaticResource stringIdConverter}, Mode=OneTime}" Name="pageFile">  
  36.                             <dxr:RibbonPageGroup Caption="{Binding Source={StaticResource stringIdConverter}, ConverterParameter=Caption_GroupCommon, Converter={StaticResource stringIdConverter}, Mode=OneTime}" Name="grpCommon" ShowCaptionButton="False">  
  37.                                 <dxb:BarButtonItemLink BarItemName="biFileNew" />  
  38.                                 <dxb:BarButtonItemLink BarItemName="biFileSaveAs" />  
  39.                                 <dxb:BarButtonItemLink BarItemName="biFilePrint" />  
  40.                                 <dxb:BarButtonItemLink BarItemName="biFilePrintPreview" />  
  41.                                 <dxb:BarButtonItemLink BarItemName="biFileBrowserPrint" />  
  42.                                 <dxb:BarButtonItemLink BarItemName="biFileBrowserPrintPreview" />  
  43.                                 <dxb:BarButtonItemLink BarItemName="biEditUndo" />  
  44.                                 <dxb:BarButtonItemLink BarItemName="biEditRedo" />  
  45.                             </dxr:RibbonPageGroup>  
  46.                             <dxr:RibbonPageGroup Caption="Ribbon Page Group 1" Name="ribbonPageGroup1">  
  47.                                 <dxb:BarButtonItemLink BarItemName="barButtonItemLoad" />  
  48.                                 <dxb:BarButtonItemLink BarItemName="barButtonItemSave" />  
  49.                             </dxr:RibbonPageGroup>  
  50.                             <dxr:RibbonPageGroup Caption="Ribbon Page Group 2" Name="ribbonPageGroup2">  
  51.                                 <dxb:BarStaticItemLink BarItemName="barStaticItemMsg" />  
  52.                             </dxr:RibbonPageGroup>  
  53.                         </dxr:RibbonPage>  
  54.                     </dxr:RibbonDefaultPageCategory>  
  55.                 </dxr:RibbonControl>  
  56.                 <dxre:RichEditControl Name="richEditControl1" BarManager="{Binding ElementName=barManager1, Mode=OneTime}" Ribbon="{Binding ElementName=ribbonControl1, Mode=OneTime}" />  
  57.             </dx:DockPanel>  
  58.         </dxb:BarManager>  
  59.     </Grid>  
  60. </UserControl>  


2、主程序逻辑部分MainPage.xaml.cs:

 

 

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Net;  
  5. using System.Windows;  
  6. using System.Windows.Controls;  
  7. using System.Windows.Documents;  
  8. using System.Windows.Input;  
  9. using System.Windows.Media;  
  10. using System.Windows.Media.Animation;  
  11. using System.Windows.Shapes;  
  12. using System.IO;  
  13. using DevExpress.XtraRichEdit;  
  14. using System.Threading;  
  15.   
  16. namespace RichEdit  
  17. {  
  18.     public partial class MainPage : UserControl  
  19.     {  
  20.         public MainPage()  
  21.         {  
  22.             InitializeComponent();  
  23.         }  
  24.   
  25.         String uri = "http://localhost:8888/upload/UploadServlet";  
  26.   
  27.         private void barButtonItemLoad_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)  
  28.         {  
  29.             MessageBox.Show("Load Begin");  
  30.   
  31.             ServerStreamLoad ssl = new ServerStreamLoad();  
  32.             ssl.Rp = new ShowLoadResultDelegate(ShowLoadResult);  
  33.             ssl.Load(uri);  
  34.         }  
  35.   
  36.         private void barButtonItemSave_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)  
  37.         {  
  38.             MessageBox.Show("Save Begin");  
  39.   
  40.             WebRequest request = WebRequest.Create(new Uri(uri));  
  41.   
  42.             Dictionary<String, String> nvc = new Dictionary<String, String>();  
  43.             nvc.Add("name""value");  
  44.             nvc.Add("name1""value1");  
  45.   
  46.             ServerStreamSave sss = new ServerStreamSave();  
  47.             sss.Rp = new ShowSaveResultDelegate(ShowSaveResult);  
  48.   
  49.             Stream stream = new MemoryStream();  
  50.             this.richEditControl1.SaveDocument(stream, DocumentFormat.Rtf);  
  51.             sss.Save(request, nvc, stream);  
  52.         }  
  53.   
  54.         // 处理Load结果  
  55.         public void ShowLoadResult(Stream stream)  
  56.         {  
  57.             String msg = "OK";  
  58.             if (this.barStaticItemMsg.CheckAccess())  
  59.             {  
  60.                 this.barStaticItemMsg.Content = msg;  
  61.             }  
  62.             else  
  63.             {  
  64.                 Dispatcher.BeginInvoke(() =>  
  65.                 {  
  66.                     this.barStaticItemMsg.Content = msg;  
  67.                 });  
  68.             }  
  69.   
  70.             using (stream)  
  71.             {  
  72.                 if (this.richEditControl1.CheckAccess())  
  73.                 {  
  74.                     this.richEditControl1.LoadDocument(stream, DocumentFormat.Rtf);  
  75.                 }  
  76.                 else  
  77.                 {  
  78.                     Dispatcher.BeginInvoke(() =>  
  79.                     {  
  80.                         this.richEditControl1.LoadDocument(stream, DocumentFormat.Rtf);  
  81.                     });  
  82.                 }  
  83.             }  
  84.         }  
  85.   
  86.         // 处理Save结果  
  87.         public void ShowSaveResult(String msg)  
  88.         {  
  89.             if (this.barStaticItemMsg.CheckAccess())  
  90.             {  
  91.                 this.barStaticItemMsg.Content = msg;  
  92.             }  
  93.             else  
  94.             {  
  95.                 Dispatcher.BeginInvoke(() =>  
  96.                 {  
  97.                     this.barStaticItemMsg.Content = msg;  
  98.                 });  
  99.             }  
  100.         }  
  101.     }  
  102.   
  103.     // 处理结果的委托  
  104.     public delegate void ShowLoadResultDelegate(Stream stream);  
  105.     public delegate void ShowSaveResultDelegate(String s);  
  106. }  


3、数据流异步下载部分ServerStreamLoad.cs:

 

 

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Net;  
  3. using System.Windows;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Documents;  
  6. using System.Windows.Ink;  
  7. using System.Windows.Input;  
  8. using System.Windows.Media;  
  9. using System.Windows.Media.Animation;  
  10. using System.Windows.Shapes;  
  11. using System.IO;  
  12.   
  13. namespace RichEdit  
  14. {  
  15.     public class ServerStreamLoad  
  16.     {  
  17.         ShowLoadResultDelegate rp;  
  18.   
  19.         public ShowLoadResultDelegate Rp  
  20.         {  
  21.             get { return rp; }  
  22.             set { rp = value; }  
  23.         }  
  24.   
  25.         public void Load(String uri)  
  26.         {  
  27.             WebClient webClient = new WebClient();  
  28.             webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(LoadCompletedCallBack);  
  29.             webClient.OpenReadAsync(new Uri(uri));  
  30.         }  
  31.   
  32.         private void LoadCompletedCallBack(object sender, OpenReadCompletedEventArgs e)  
  33.         {  
  34.             using (Stream stream = e.Result)  
  35.             {  
  36.                 // read stream here  
  37.                 rp(stream);  
  38.             }  
  39.         }  
  40.     }  
  41. }  


4、数据流异步提交部分:

 

 

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Net;  
  3. using System.Windows;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Documents;  
  6. using System.Windows.Ink;  
  7. using System.Windows.Input;  
  8. using System.Windows.Media;  
  9. using System.Windows.Media.Animation;  
  10. using System.Windows.Shapes;  
  11. using System.IO;  
  12. using System.Collections.Generic;  
  13. using System.Windows.Threading;  
  14.   
  15. namespace RichEdit  
  16. {  
  17.     public class ServerStreamSave  
  18.     {  
  19.         static ShowSaveResultDelegate rp;  
  20.   
  21.         public ShowSaveResultDelegate Rp  
  22.         {  
  23.             get { return rp; }  
  24.             set { rp = value; }  
  25.         }  
  26.   
  27.   
  28.         public void Save(WebRequest request, Dictionary<String, String> nvc, Stream stream)  
  29.         {  
  30.             request.Method = "POST";  
  31.   
  32.             UploadState us = new UploadState();  
  33.             us.Req = request;  
  34.             us.Nvc = nvc;  
  35.             us.Stream = stream;  
  36.   
  37.             request.BeginGetRequestStream(new AsyncCallback(SaveRequestReadyCallBack), us);  
  38.         }  
  39.   
  40.         private void SaveRequestReadyCallBack(IAsyncResult asyncResult)  
  41.         {  
  42.             string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");  
  43.             byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");  
  44.   
  45.             WebRequest request = ((UploadState)(asyncResult.AsyncState)).Req as WebRequest;  
  46.             request.ContentType = "multipart/form-data; boundary=" + boundary;  
  47.             request.UseDefaultCredentials = true;  
  48.   
  49.             Stream rs = request.EndGetRequestStream(asyncResult);  
  50.   
  51.             // 1.write boundery and key-value pairs  
  52.             string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";  
  53.             IDictionary<String, String> nvc = ((UploadState)(asyncResult.AsyncState)).Nvc as IDictionary<String, String>;  
  54.             foreach (string key in nvc.Keys)  
  55.             {  
  56.                 rs.Write(boundarybytes, 0, boundarybytes.Length);  
  57.                 string formitem = string.Format(formdataTemplate, key, nvc[key]);  
  58.                 byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);  
  59.                 rs.Write(formitembytes, 0, formitembytes.Length);  
  60.             }  
  61.   
  62.             rs.Write(boundarybytes, 0, boundarybytes.Length);  
  63.   
  64.             // 2.write head  
  65.             string file = "file";  
  66.             string paramName = "file";  
  67.             string contentType = "unknown";  
  68.   
  69.             string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";  
  70.             string header = string.Format(headerTemplate, paramName, file, contentType);  
  71.             byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);  
  72.   
  73.             rs.Write(headerbytes, 0, headerbytes.Length);  
  74.   
  75.             // 3.write stream here,the stream will be closed by invoker  
  76.             using (Stream stream = ((UploadState)(asyncResult.AsyncState)).Stream as Stream)  
  77.             {  
  78.                 stream.Position = 0;  
  79.                 //byte[] buffer = System.Text.Encoding.UTF8.GetBytes("aaa我11");  
  80.                 byte[] data = new byte[4096];  
  81.   
  82.                 int count = stream.Read(data, 0, 4096);  
  83.                 while (count > 0)  
  84.                 {  
  85.                     rs.Write(data, 0, count);  
  86.                     count = stream.Read(data, 0, 4096);  
  87.                 }  
  88.             }  
  89.   
  90.             //rs.Write(buffer, 0, buffer.Length);  
  91.   
  92.             // 4.write trailer  
  93.             byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");  
  94.   
  95.             rs.Write(trailer, 0, trailer.Length);  
  96.   
  97.             rs.Flush();  
  98.             rs.Close();  
  99.   
  100.             request.BeginGetResponse(new AsyncCallback(SaveResponseReadyCallBack), request);  
  101.         }  
  102.   
  103.         private void SaveResponseReadyCallBack(IAsyncResult asyncResult)  
  104.         {  
  105.             WebRequest request = asyncResult.AsyncState as WebRequest;  
  106.             WebResponse response = request.EndGetResponse(asyncResult);  
  107.   
  108.             using (Stream responseStream = response.GetResponseStream())  
  109.             {  
  110.                 StreamReader reader = new StreamReader(responseStream);  
  111.   
  112.                 // check response result by return msg.  
  113.                 String msg = reader.ReadToEnd();  
  114.   
  115.                 rp(msg);  
  116.             }  
  117.         }  
  118.     }  
  119. }  


5、异步请求提交,回调封装参数部分UploadState.cs:

 

 

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Net;  
  3. using System.Windows;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Documents;  
  6. using System.Windows.Ink;  
  7. using System.Windows.Input;  
  8. using System.Windows.Media;  
  9. using System.Windows.Media.Animation;  
  10. using System.Windows.Shapes;  
  11. using System.Collections;  
  12. using System.Collections.Generic;  
  13. using System.IO;  
  14.   
  15. namespace RichEdit  
  16. {  
  17.     public class UploadState  
  18.     {  
  19.         IDictionary<String, String> nvc = null;  
  20.   
  21.         public IDictionary<String, String> Nvc  
  22.         {  
  23.             get { return nvc; }  
  24.             set { nvc = value; }  
  25.         }  
  26.   
  27.         WebRequest req = null;  
  28.   
  29.         public WebRequest Req  
  30.         {  
  31.             get { return req; }  
  32.             set { req = value; }  
  33.         }  
  34.   
  35.         Stream stream;  
  36.   
  37.         public Stream Stream  
  38.         {  
  39.             get { return stream; }  
  40.             set { stream = value; }  
  41.         }  
  42.     }  
  43. }  


(二)服务器端使用commons-fileupload-1.2.2.jar实现上传:

 

1、web.xml配置:

 

[html] view plaincopy
 
  1. <servlet>  
  2.     <display-name>UploadServlet</display-name>  
  3.     <servlet-name>UploadServlet</servlet-name>  
  4.     <servlet-class>com.liyj.upload.servlet.UploadServlet</servlet-class>  
  5. </servlet>  
  6. <servlet-mapping>  
  7.     <servlet-name>UploadServlet</servlet-name>  
  8.     <url-pattern>/UploadServlet</url-pattern>  
  9. </servlet-mapping>  


2、UploadServlet.java(取打包的参数和附件)

 

 

[java] view plaincopy
 
  1. package com.liyj.upload.servlet;  
  2.   
  3. import java.io.*;  
  4. import java.util.List;  
  5.   
  6. import javax.servlet.*;  
  7. import javax.servlet.http.*;  
  8.   
  9. import org.apache.commons.fileupload.FileItem;  
  10. import org.apache.commons.fileupload.FileUploadException;  
  11. import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
  12. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  13.   
  14. public class UploadServlet extends HttpServlet {  
  15.     public void init(ServletConfig config) throws ServletException {  
  16.         super.init(config);  
  17.     }  
  18.   
  19.     public void doGet(HttpServletRequest request, HttpServletResponse response) {  
  20.         ServletOutputStream out = null;  
  21.           
  22.         System.out.println("into doGet..");  
  23.           
  24.         try {  
  25.             out = response.getOutputStream();  
  26.               
  27.             FileInputStream fis = new FileInputStream("D:\\file");  
  28.               
  29.             byte[] data = new byte[4096];  
  30.               
  31.             int count = fis.read(data);  
  32.             while(count > 0) {  
  33.                 out.write(data, 0, count);  
  34.                 count = fis.read(data);  
  35.             }  
  36.               
  37.             fis.close();  
  38.             out.flush();  
  39.             out.close();  
  40.         } catch (Exception e)  
  41.         {  
  42.             e.printStackTrace();  
  43.         }         
  44.     }  
  45.     public void doPost(HttpServletRequest request, HttpServletResponse response) {  
  46.         ServletOutputStream out = null;  
  47.         System.out.println("into doPost..");  
  48.         DiskFileItemFactory factory = new DiskFileItemFactory();  
  49.         String path = "D:\\";  
  50.         factory.setRepository(new File(path));  
  51.         factory.setSizeThreshold(1024 * 1024);  
  52.         ServletFileUpload upload = new ServletFileUpload(factory);  
  53.           
  54.         try {  
  55.             out = response.getOutputStream();  
  56.               
  57.             List<FileItem> list = upload.parseRequest(request);  
  58.             for (FileItem item : list) {  
  59.                 if (item.isFormField()) {  
  60.                     String name = item.getFieldName();  
  61.                     String value = item.getString("gbk");  
  62.   
  63.                     out.println(name + ":" + value);  
  64.                 } else {  
  65.                     String name = item.getFieldName();  
  66.                     String value = item.getName();  
  67.                     int start = value.lastIndexOf("\\");  
  68.                     String fileName = value.substring(start + 1);  
  69.                     //request.setAttribute(name, fileName);  
  70.                       
  71.                     OutputStream os = new FileOutputStream(new File(path, fileName));  
  72.                     InputStream is = item.getInputStream();  
  73.                     byte[] buffer = new byte[1024];  
  74.                     int length = 0;  
  75.                     int fileLen = 0;  
  76.                     while ((length = is.read(buffer)) > 0) {  
  77.                         os.write(buffer, 0, length);  
  78.                         fileLen += length;  
  79.                     }  
  80.                     out.println("OK");  
  81.                     os.close();  
  82.                     is.close();  
  83.                 }  
  84.             }  
  85.         } catch (Exception e) {  
  86.             try {  
  87.                 out.println("NG");  
  88.             } catch (IOException e1) {  
  89.                 // TODO Auto-generated catch block  
  90.                 e1.printStackTrace();  
  91.             }  
  92.             e.printStackTrace();  
  93.         }  
  94.     }  
  95. }  

---------- THE END-----------

Silverlight技术调查(4)——完成的调查结果

上一篇:Android 仿微信朋友圈发动态功能(相册图片多选)


下一篇:友盟发布第一期国内主要社交平台活跃度数据,微信超越QQ领跑社交平台