REST client API (SPRNET-1345) :

- Added UrlEncodedFormHttpMessageConverter
- Fixed Xml based message converters
- Minor fixes & polishing
This commit is contained in:
bbaia
2010-11-28 19:03:58 +00:00
parent b8a687b86a
commit 169d210b48
36 changed files with 390 additions and 208 deletions

View File

@@ -258,7 +258,7 @@ namespace Spring.Http.Converters
#region Inner class definitions
// TODO : Move this class
// TODO : Move this class ?
internal class IgnoreCloseMemoryStream : MemoryStream
{
public IgnoreCloseMemoryStream()
@@ -274,15 +274,13 @@ namespace Spring.Http.Converters
{
this.Position = 0;
int bufferSize = 65536;
byte[] buffer = new byte[bufferSize];
// From .NET 4.0 Stream.CopyTo method
int bytesCount;
while ((bytesCount = this.Read(buffer, 0, buffer.Length)) > 0)
byte[] buffer = new byte[0x1000];
while ((bytesCount = this.Read(buffer, 0, buffer.Length)) != 0)
{
dest.Write(buffer, 0, bytesCount);
}
dest.Flush();
base.Close();
}

View File

@@ -21,7 +21,6 @@
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Spring.Http.Converters
{

View File

@@ -19,7 +19,6 @@
#endregion
using System;
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;

View File

@@ -19,7 +19,6 @@
#endregion
using System;
using System.Net;
using System.Xml;
using System.ServiceModel.Syndication;

View File

@@ -31,7 +31,6 @@ using Spring.Util;
namespace Spring.Http.Converters.Json
{
// TODO : Support for known types, etc...
// TODO : Fix Write method
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can read and write JSON.
@@ -90,8 +89,8 @@ namespace Spring.Http.Converters.Json
protected override void WriteInternal(object content, HttpWebRequest request)
{
// Get the request encoding
MediaType mediaType = MediaType.ParseMediaType(request.ContentType);
Encoding encoding;
MediaType mediaType = MediaType.ParseMediaType(request.ContentType);
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
@@ -109,13 +108,15 @@ namespace Spring.Http.Converters.Json
using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(requestStream, encoding, false))
{
serializer.WriteObject(jsonWriter, content);
jsonWriter.Flush();
}
// Set the content length in the request headers
request.ContentLength = requestStream.Length;
requestStream.CopyToAndClose(request.GetRequestStream());
using (Stream postStream = request.GetRequestStream())
{
requestStream.CopyToAndClose(postStream);
}
}
}
}

View File

@@ -73,13 +73,14 @@ namespace Spring.Http.Converters
{
// Get the response encoding
Encoding encoding;
if (!StringUtils.HasText(response.CharacterSet))
MediaType mediaType = MediaType.ParseMediaType(response.ContentType);
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = DEFAULT_CHARSET;
}
else
{
encoding = Encoding.GetEncoding(response.CharacterSet);
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
// Get the response stream

View File

@@ -0,0 +1,181 @@
#region License
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Text;
using System.Collections.Specialized;
using Spring.Util;
namespace Spring.Http.Converters
{
/// <summary>
/// Implementation of <see cref="IHttpMessageConverter"/> that can handle form data,
/// including multipart form data (i.e. file uploads).
/// </summary>
/// <remarks>
/// <para>
/// This converter supports the 'application/x-www-form-urlencoded' media type.
/// </para>
/// <para>
/// For example, the following snippet shows how to submit an HTML form:
/// <code>
/// RestTemplate template = new RestTemplate(); // UrlEncodedFormHttpMessageConverter is configured by default
/// NameValueCollection form = new NameValueCollection();
/// form.Add("field 1", "value 1");
/// form.Add("field 2", "value 2");
/// form.Add("field 2", "value 3");
/// template.PostForLocation("http://example.com/myForm", form);
/// </code>
/// </para>
/// </remarks>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
public class UrlEncodedFormHttpMessageConverter : AbstractHttpMessageConverter
{
private Encoding charset = Encoding.GetEncoding("ISO-8859-1");
/// <summary>
/// Sets the encoding used for writing form data.
/// </summary>
public Encoding Charset
{
set { charset = value; }
}
/// <summary>
/// Creates a new instance of the <see cref="UrlEncodedFormHttpMessageConverter"/>
/// with 'application/x-www-form-urlencoded' media type.
/// </summary>
public UrlEncodedFormHttpMessageConverter() :
base(MediaType.APPLICATION_FORM_URLENCODED)
{
}
/// <summary>
/// Indicates whether the given class is supported by this converter.
/// </summary>
/// <param name="type">The type to test for support.</param>
/// <returns><see langword="true"/> if supported; otherwise <see langword="false"/></returns>
protected override bool Supports(Type type)
{
return type.Equals(typeof(NameValueCollection));
}
/// <summary>
/// Abstract template method that reads the actualy object. Invoked from <see cref="M:Read"/>.
/// </summary>
/// <typeparam name="T">The type of object to return.</typeparam>
/// <param name="response">The HTTP response to read from.</param>
/// <returns>The converted object.</returns>
protected override T ReadInternal<T>(HttpWebResponse response)
{
// Get the response encoding
Encoding encoding;
MediaType mediaType = MediaType.ParseMediaType(response.ContentType);
if (mediaType == null || !StringUtils.HasText(mediaType.CharSet))
{
encoding = this.charset;
}
else
{
encoding = Encoding.GetEncoding(mediaType.CharSet);
}
// Get the response stream
string body;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
{
body = reader.ReadToEnd();
}
string[] pairs = body.Split('&');
NameValueCollection result = new NameValueCollection(pairs.Length);
foreach (string pair in pairs)
{
int idx = pair.IndexOf('=');
if (idx == -1)
{
result.Add(HttpUtility.UrlDecode(pair, this.charset), null);
}
else
{
string name = HttpUtility.UrlDecode(pair.Substring(0, idx), this.charset);
string value = HttpUtility.UrlDecode(pair.Substring(idx + 1), this.charset);
result.Add(name, value);
}
}
return result as T;
}
/// <summary>
/// Abstract template method that writes the actual body. Invoked from <see cref="M:Write"/>.
/// </summary>
/// <param name="content">The object to write to the HTTP request.</param>
/// <param name="request">The HTTP request to write to.</param>
protected override void WriteInternal(object content, HttpWebRequest request)
{
StringBuilder builder = new StringBuilder();
NameValueCollection form = content as NameValueCollection;
for(int i=0; i < form.AllKeys.Length; i++)
{
string name = form.GetKey(i);
string[] values = form.GetValues(name);
if (values == null)
{
builder.Append(HttpUtility.UrlEncode(name, this.charset));
}
else
{
for (int j = 0; j < values.Length; j++)
{
string value = values[j];
builder.Append(HttpUtility.UrlEncode(name, this.charset));
builder.Append('=');
builder.Append(HttpUtility.UrlEncode(value, this.charset));
if (j != (values.Length - 1))
{
builder.Append('&');
}
}
}
if (i != (form.AllKeys.Length - 1))
{
builder.Append('&');
}
}
// Create a byte array of the data we want to send
byte[] byteData = this.charset.GetBytes(builder.ToString());
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write to the request
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
}
}
}

View File

@@ -40,7 +40,7 @@ namespace Spring.Http.Converters.Xml
/// <summary>
/// Default encoding for XML.
/// </summary>
public static readonly Encoding DEFAULT_CHARSET = Encoding.UTF8;
public static readonly Encoding DEFAULT_CHARSET = new UTF8Encoding(false); // Remove byte Order Mask (BOM) when using XmlTextWriter
private XmlReaderSettings _xmlReaderSettings;
@@ -122,13 +122,15 @@ namespace Spring.Http.Converters.Xml
using (XmlTextWriter xmlWriter = new XmlTextWriter(requestStream, encoding))
{
WriteXml(xmlWriter, content, request);
xmlWriter.Flush();
}
// Set the content length in the request headers
request.ContentLength = requestStream.Length;
requestStream.CopyToAndClose(request.GetRequestStream());
using (Stream postStream = request.GetRequestStream())
{
requestStream.CopyToAndClose(postStream);
}
}
}

View File

@@ -20,10 +20,8 @@
#endregion
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Runtime.Serialization;
namespace Spring.Http.Converters.Xml
@@ -40,7 +38,7 @@ namespace Spring.Http.Converters.Xml
/// This can be overridden by setting the <see cref="P:SupportedMediaTypes"/> property.
/// </para>
/// <para>
/// This converter can read classes annotated with <see cref="DataContractAttribute"/> and <see cref="CollectionDataContractAttribute"/>, and write classes
/// This converter can read classes annotated with <see cref="DataContractAttribute"/> and <see cref="CollectionDataContractAttribute"/>, and write classes
/// annotated with with {@link XmlRootElement}, or subclasses thereof.
/// </para>
/// </remarks>

View File

@@ -18,8 +18,6 @@
#endregion
using System;
namespace Spring.Http
{
/// <summary>

View File

@@ -18,7 +18,6 @@
#endregion
using System;
using System.Net;
namespace Spring.Http.Rest

View File

@@ -18,7 +18,6 @@
#endregion
using System;
using System.Net;
namespace Spring.Http.Rest

View File

@@ -22,8 +22,6 @@ using System;
using System.Net;
using System.Collections.Generic;
using Spring.Http;
namespace Spring.Http.Rest
{
/// <summary>

View File

@@ -19,14 +19,11 @@
#endregion
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Spring.Http;
using Spring.Http.Converters;
using Spring.Http.Converters.Xml;
using Spring.Http.Converters.Json;
using Spring.Http.Converters.Feed;
using Spring.Http.Rest.Support;
using UriTemplate = Spring.Util.UriTemplate; // UriTemplate in .NET Framework since 3.5
@@ -201,6 +198,7 @@ namespace Spring.Http.Rest
this._messageConverters.Add(new ByteArrayHttpMessageConverter());
this._messageConverters.Add(new StringHttpMessageConverter());
this._messageConverters.Add(new UrlEncodedFormHttpMessageConverter());
//this._messageConverters.Add(new XmlSerializableHttpMessageConverter());
this._messageConverters.Add(new XmlDocumentHttpMessageConverter());
#if NET_3_5

View File

@@ -23,7 +23,6 @@ using System.Net;
using System.Collections.Generic;
using Spring.Util;
using Spring.Http;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support

View File

@@ -22,7 +22,6 @@ using System;
using System.Net;
using System.Collections.Generic;
using Spring.Http;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support

View File

@@ -21,7 +21,6 @@
using System.Net;
using System.Collections.Generic;
using Spring.Http;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support

View File

@@ -23,7 +23,6 @@ using System.Net;
using System.Collections.Generic;
using Spring.Util;
using Spring.Http;
using Spring.Http.Converters;
namespace Spring.Http.Rest.Support

View File

@@ -21,8 +21,6 @@
using System;
using System.Net;
using Spring.Http;
namespace Spring.Http.Rest.Support
{
/// <summary>

View File

@@ -87,6 +87,7 @@
<Reference Include="System.ServiceModel.Web">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -98,6 +99,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Http\Converters\UrlEncodedFormHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\AbstractFeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />

View File

@@ -102,6 +102,7 @@
<Reference Include="System.configuration" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
@@ -112,6 +113,7 @@
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverter.cs" />
<Compile Include="Http\Converters\UrlEncodedFormHttpMessageConverter.cs" />
<Compile Include="Http\HttpResponseMessage.cs" />
<Compile Include="Http\HttpResponseMessage`1.cs" />
<Compile Include="Http\DefaultHttpWebRequestFactory.cs" />

View File

@@ -72,17 +72,17 @@ namespace Spring.Util
}
/// <summary>
/// Given the dictionary of variables, expands this template into a full URI.
/// Given the dictionary of variables, expands this template into a full URI.
/// The dictionary keys represent variable names, the dicitonary values variable values.
/// The order of variables is not significant.
/// </summary>
/// <example>
/// <code>
/// UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
/// IDictionary&lt;string, string&gt; uriVariables = new Dictionary&lt;String, String&gt;();
/// uriVariables.Add("booking", "42");
/// uriVariables.Add("hotel", "1");
/// Console.Out.WriteLine(template.Expand(uriVariables));
/// <code>
/// UriTemplate template = new UriTemplate("http://example.com/hotels/{hotel}/bookings/{booking}");
/// IDictionary&lt;string, string&gt; uriVariables = new Dictionary&lt;String, String&gt;();
/// uriVariables.Add("booking", "42");
/// uriVariables.Add("hotel", "1");
/// Console.Out.WriteLine(template.Expand(uriVariables));
/// </code>
/// will print: <blockquote>http://example.com/hotels/1/bookings/42</blockquote>
/// </example>
@@ -241,7 +241,7 @@ namespace Spring.Util
public Parser(string uriTemplate)
{
AssertUtils.ArgumentHasText(uriTemplate, "'uriTemplate' must not be null");
AssertUtils.ArgumentNotNull(uriTemplate, "'uriTemplate' must not be null");
int index = 0;
this.patternBuilder.Append("^");

View File

@@ -18,7 +18,6 @@
#endregion
using System;
using System.IO;
using System.Net;
@@ -50,17 +49,17 @@ namespace Spring.Http.Converters
{
Assert.IsTrue(converter.CanRead(typeof(byte[]), new MediaType("application", "octet-stream")));
Assert.IsTrue(converter.CanRead(typeof(byte[]), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(byte[]), MediaType.ALL));
Assert.IsTrue(converter.CanRead(typeof(byte[]), MediaType.ALL));
Assert.IsFalse(converter.CanRead(typeof(string), new MediaType("application", "octet-stream")));
}
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(byte[]), new MediaType("application", "octet-stream")));
Assert.IsTrue(converter.CanRead(typeof(byte[]), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(byte[]), new MediaType("application", "octet-stream")));
Assert.IsTrue(converter.CanWrite(typeof(byte[]), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(byte[]), MediaType.ALL));
Assert.IsFalse(converter.CanRead(typeof(string), new MediaType("application", "octet-stream")));
Assert.IsFalse(converter.CanWrite(typeof(string), new MediaType("application", "octet-stream")));
}
[Test]

View File

@@ -62,11 +62,11 @@ namespace Spring.Http.Converters.Feed
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(SyndicationFeed), new MediaType("application", "atom+xml")));
Assert.IsTrue(converter.CanRead(typeof(SyndicationItem), new MediaType("application", "atom+xml")));
Assert.IsTrue(converter.CanRead(typeof(SyndicationFeed), new MediaType("text", "xml")));
Assert.IsFalse(converter.CanRead(typeof(string), new MediaType("application", "atom+xml")));
Assert.IsFalse(converter.CanRead(typeof(SyndicationFeed), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationFeed), new MediaType("application", "atom+xml")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationItem), new MediaType("application", "atom+xml")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationFeed), new MediaType("text", "xml")));
Assert.IsFalse(converter.CanWrite(typeof(string), new MediaType("application", "atom+xml")));
Assert.IsFalse(converter.CanWrite(typeof(SyndicationFeed), new MediaType("text", "plain")));
}
[Test]
@@ -74,7 +74,7 @@ namespace Spring.Http.Converters.Feed
{
DateTime now = DateTime.Now;
string body = String.Format("<feed xmlns=\"http://www.w3.org/2005/Atom\"><title type=\"text\">Test Feed</title><subtitle type=\"text\">This is a test feed</subtitle><id>Atom10FeedHttpMessageConverterTests.Write</id><rights type=\"text\">Copyright 2010</rights><updated>{0}</updated><author><name>Bruno Baïa</name><uri>http://www.springframework.net/bbaia</uri><email>bruno.baia@springframework.net</email></author><link rel=\"alternate\" href=\"http://www.springframework.net/Feed\" /></feed>",
string body = String.Format("<feed xmlns=\"http://www.w3.org/2005/Atom\"><title type=\"text\">Test Feed</title><subtitle type=\"text\">This is a test feed</subtitle><id>Atom10FeedHttpMessageConverterTests.Write</id><rights type=\"text\">Copyright 2010</rights><updated>{0}</updated><author><name>Bruno Baïa</name><uri>http://www.springframework.net/bbaia</uri><email>bruno.baia@springframework.net</email></author><link rel=\"alternate\" href=\"http://www.springframework.net/Feed\" /></feed>",
now.ToString("yyyy-MM-ddTHH:mm:sszzz", CultureInfo.InvariantCulture));
HttpWebResponse webResponse = mocks.CreateMock<HttpWebResponse>();
@@ -105,7 +105,7 @@ namespace Spring.Http.Converters.Feed
DateTime now = DateTime.Now;
string expectedBody = String.Format("<feed xmlns=\"http://www.w3.org/2005/Atom\"><title type=\"text\">Test Feed</title><subtitle type=\"text\">This is a test feed</subtitle><id>Atom10FeedHttpMessageConverterTests.Write</id><rights type=\"text\">Copyright 2010</rights><updated>{0}</updated><author><name>Bruno Baïa</name><uri>http://www.springframework.net/bbaia</uri><email>bruno.baia@springframework.net</email></author><link rel=\"alternate\" href=\"http://www.springframework.net/Feed\" /></feed>",
string expectedBody = String.Format("<feed xmlns=\"http://www.w3.org/2005/Atom\"><title type=\"text\">Test Feed</title><subtitle type=\"text\">This is a test feed</subtitle><id>Atom10FeedHttpMessageConverterTests.Write</id><rights type=\"text\">Copyright 2010</rights><updated>{0}</updated><author><name>Bruno Baïa</name><uri>http://www.springframework.net/bbaia</uri><email>bruno.baia@springframework.net</email></author><link rel=\"alternate\" href=\"http://www.springframework.net/Feed\" /></feed>",
now.ToString("yyyy-MM-ddTHH:mm:sszzz", CultureInfo.InvariantCulture));
SyndicationFeed body = new SyndicationFeed("Test Feed", "This is a test feed", new Uri("http://www.springframework.net/Feed"), "Atom10FeedHttpMessageConverterTests.Write", now);

View File

@@ -62,12 +62,12 @@ namespace Spring.Http.Converters.Feed
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(SyndicationFeed), new MediaType("application", "rss+xml")));
Assert.IsTrue(converter.CanRead(typeof(SyndicationItem), new MediaType("application", "rss+xml")));
Assert.IsTrue(converter.CanRead(typeof(SyndicationFeed), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanRead(typeof(SyndicationFeed), new MediaType("text", "xml")));
Assert.IsFalse(converter.CanRead(typeof(string), new MediaType("application", "rss+xml")));
Assert.IsFalse(converter.CanRead(typeof(SyndicationFeed), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationFeed), new MediaType("application", "rss+xml")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationItem), new MediaType("application", "rss+xml")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationFeed), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(SyndicationFeed), new MediaType("text", "xml")));
Assert.IsFalse(converter.CanWrite(typeof(string), new MediaType("application", "rss+xml")));
Assert.IsFalse(converter.CanWrite(typeof(SyndicationFeed), new MediaType("text", "plain")));
}
[Test]
@@ -75,7 +75,7 @@ namespace Spring.Http.Converters.Feed
{
DateTime now = DateTime.Now;
string body = String.Format("<rss xmlns:a10=\"http://www.w3.org/2005/Atom\" version=\"2.0\"><channel><title>Test Feed</title><link>http://www.springframework.net/Feed</link><description>This is a test feed</description><copyright>Copyright 2010</copyright><managingEditor>bruno.baia@springframework.net</managingEditor><lastBuildDate>{0}</lastBuildDate><a10:id>Atom10FeedHttpMessageConverterTests.Write</a10:id></channel></rss>",
string body = String.Format("<rss xmlns:a10=\"http://www.w3.org/2005/Atom\" version=\"2.0\"><channel><title>Test Feed</title><link>http://www.springframework.net/Feed</link><description>This is a test feed</description><copyright>Copyright 2010</copyright><managingEditor>bruno.baia@springframework.net</managingEditor><lastBuildDate>{0}</lastBuildDate><a10:id>Atom10FeedHttpMessageConverterTests.Write</a10:id></channel></rss>",
now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture).Remove(29, 1));
HttpWebResponse webResponse = mocks.CreateMock<HttpWebResponse>();
@@ -104,7 +104,7 @@ namespace Spring.Http.Converters.Feed
DateTime now = DateTime.Now;
string expectedBody = String.Format("<rss xmlns:a10=\"http://www.w3.org/2005/Atom\" version=\"2.0\"><channel><title>Test Feed</title><link>http://www.springframework.net/Feed</link><description>This is a test feed</description><copyright>Copyright 2010</copyright><managingEditor>bruno.baia@springframework.net</managingEditor><lastBuildDate>{0}</lastBuildDate><a10:id>Atom10FeedHttpMessageConverterTests.Write</a10:id></channel></rss>",
string expectedBody = String.Format("<rss xmlns:a10=\"http://www.w3.org/2005/Atom\" version=\"2.0\"><channel><title>Test Feed</title><link>http://www.springframework.net/Feed</link><description>This is a test feed</description><copyright>Copyright 2010</copyright><managingEditor>bruno.baia@springframework.net</managingEditor><lastBuildDate>{0}</lastBuildDate><a10:id>Atom10FeedHttpMessageConverterTests.Write</a10:id></channel></rss>",
now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture).Remove(29, 1));
SyndicationFeed body = new SyndicationFeed("Test Feed", "This is a test feed", new Uri("http://www.springframework.net/Feed"), "Atom10FeedHttpMessageConverterTests.Write", now);

View File

@@ -55,8 +55,8 @@ namespace Spring.Http.Converters.Json
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(CustomClass), new MediaType("application", "json")));
Assert.IsFalse(converter.CanRead(typeof(CustomClass), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(CustomClass), new MediaType("application", "json")));
Assert.IsFalse(converter.CanWrite(typeof(CustomClass), new MediaType("text", "xml")));
}
[Test]

View File

@@ -18,7 +18,6 @@
#endregion
using System;
using System.IO;
using System.Net;
using System.Text;
@@ -50,7 +49,7 @@ namespace Spring.Http.Converters
public void CanRead()
{
Assert.IsTrue(converter.CanRead(typeof(string), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(string), MediaType.ALL));
Assert.IsTrue(converter.CanRead(typeof(string), MediaType.ALL));
Assert.IsTrue(converter.CanRead(typeof(string), new MediaType("application", "xml")));
Assert.IsFalse(converter.CanRead(typeof(int[]), new MediaType("text", "plain")));
}
@@ -58,20 +57,23 @@ namespace Spring.Http.Converters
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(string), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(string), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(string), MediaType.ALL));
Assert.IsTrue(converter.CanRead(typeof(string), new MediaType("application", "xml")));
Assert.IsFalse(converter.CanRead(typeof(int[]), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(string), new MediaType("application", "xml")));
Assert.IsFalse(converter.CanWrite(typeof(int[]), new MediaType("text", "plain")));
}
[Test]
public void Read()
{
string body = "Hello Bruno Baïa";
string charSet = "utf-8";
Encoding charSetEncoding = Encoding.GetEncoding(charSet);
MediaType mediaType = new MediaType("text", "plain", charSet);
HttpWebResponse webResponse = mocks.CreateMock<HttpWebResponse>();
Expect.Call<Stream>(webResponse.GetResponseStream()).Return(new MemoryStream(Encoding.UTF8.GetBytes(body)));
Expect.Call<string>(webResponse.CharacterSet).Return("utf-8").Repeat.Twice();
Expect.Call<string>(webResponse.ContentType).Return(mediaType.ToString());
mocks.ReplayAll();
@@ -89,9 +91,10 @@ namespace Spring.Http.Converters
string body = "H\u00e9llo W\u00f6rld";
string charSet = "ISO-8859-1";
Encoding charSetEncoding = Encoding.GetEncoding(charSet);
MediaType mediaType = new MediaType("text", "plain", charSet);
HttpWebRequest webRequest = mocks.CreateMock<HttpWebRequest>();
Expect.Call(webRequest.ContentType = "text/plain;charset=ISO-8859-1").PropertyBehavior();
Expect.Call(webRequest.ContentType = mediaType.ToString()).PropertyBehavior();
Expect.Call(webRequest.ContentLength = 1337).PropertyBehavior();
Expect.Call<Stream>(webRequest.GetRequestStream()).Return(requestStream);

View File

@@ -0,0 +1,122 @@
#region License
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Specialized;
using NUnit.Framework;
using Rhino.Mocks;
namespace Spring.Http.Converters
{
/// <summary>
/// Unit tests for the UrlEncodedFormHttpMessageConverter class.
/// </summary>
/// <author>Arjen Poutsma</author>
/// <author>Bruno Baia (.NET)</author>
[TestFixture]
public class UrlEncodedFormHttpMessageConverterTests
{
private UrlEncodedFormHttpMessageConverter converter;
private MockRepository mocks;
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
converter = new UrlEncodedFormHttpMessageConverter();
}
[Test]
public void CanRead()
{
Assert.IsTrue(converter.CanRead(typeof(NameValueCollection), new MediaType("application", "x-www-form-urlencoded")));
Assert.IsFalse(converter.CanRead(typeof(NameValueCollection), new MediaType("application", "xml")));
Assert.IsFalse(converter.CanRead(typeof(string), new MediaType("application", "x-www-form-urlencoded")));
}
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanWrite(typeof(NameValueCollection), new MediaType("application", "x-www-form-urlencoded")));
Assert.IsFalse(converter.CanWrite(typeof(NameValueCollection), new MediaType("application", "xml")));
Assert.IsFalse(converter.CanWrite(typeof(string), new MediaType("application", "x-www-form-urlencoded")));
}
[Test]
public void Read()
{
String body = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3";
string charSet = "ISO-8859-1";
Encoding charSetEncoding = Encoding.GetEncoding(charSet);
MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", charSet);
HttpWebResponse webResponse = mocks.CreateMock<HttpWebResponse>();
Expect.Call<Stream>(webResponse.GetResponseStream()).Return(new MemoryStream(Encoding.UTF8.GetBytes(body)));
Expect.Call<string>(webResponse.ContentType).Return(mediaType.ToString());
mocks.ReplayAll();
NameValueCollection result = converter.Read<NameValueCollection>(webResponse);
Assert.AreEqual(3, result.Count, "Invalid result");
Assert.AreEqual(1, result.GetValues(0).Length, "Invalid result");
Assert.AreEqual("value 1", result.GetValues(0)[0], "Invalid result");
Assert.AreEqual(2, result.GetValues("name 2").Length, "Invalid result");
Assert.AreEqual("value 2+1", result.GetValues("name 2")[0], "Invalid result");
Assert.AreEqual("value 2+2", result.GetValues("name 2")[1], "Invalid result");
Assert.IsNull(result["name 3"], "Invalid result");
mocks.VerifyAll();
}
[Test]
public void Write()
{
MemoryStream requestStream = new MemoryStream();
string expectedBody = "name+1=value+1&name+2=value+2%2b1&name+2=value+2%2b2&name+3";
NameValueCollection body = new NameValueCollection();
body.Add("name 1", "value 1");
body.Add("name 2", "value 2+1");
body.Add("name 2", "value 2+2");
body.Add("name 3", null);
string charSet = "ISO-8859-1";
Encoding charSetEncoding = Encoding.GetEncoding(charSet);
MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", charSet);
HttpWebRequest webRequest = mocks.CreateMock<HttpWebRequest>();
Expect.Call(webRequest.ContentType = mediaType.ToString()).PropertyBehavior();
Expect.Call(webRequest.ContentLength = 1337).PropertyBehavior();
Expect.Call<Stream>(webRequest.GetRequestStream()).Return(requestStream);
mocks.ReplayAll();
converter.Write(body, null, webRequest);
byte[] result = requestStream.ToArray();
Assert.AreEqual(expectedBody, charSetEncoding.GetString(result), "Invalid result");
mocks.VerifyAll();
}
}
}

View File

@@ -63,10 +63,10 @@ namespace Spring.Http.Converters.Xml
{
Assert.IsTrue(converter.CanWrite(typeof(DataContractClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(DataContractClass), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanRead(typeof(DataContractClass), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanRead(typeof(DataContractClass), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanRead(typeof(NonDataContractClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanRead(typeof(CollectionDataContractClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(DataContractClass), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanWrite(typeof(DataContractClass), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanWrite(typeof(NonDataContractClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(CollectionDataContractClass), new MediaType("application", "xml")));
}
[Test]
@@ -107,12 +107,8 @@ namespace Spring.Http.Converters.Xml
converter.Write(body, null, webRequest);
requestStream.Position = 0;
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
Assert.AreEqual(expectedBody, result, "Invalid result");
}
byte[] result = requestStream.ToArray();
Assert.AreEqual(expectedBody, Encoding.UTF8.GetString(result), "Invalid result");
mocks.VerifyAll();
}

View File

@@ -63,9 +63,9 @@ namespace Spring.Http.Converters.Xml
{
Assert.IsTrue(converter.CanWrite(typeof(XElement), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(XElement), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanRead(typeof(XElement), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanRead(typeof(XElement), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanRead(typeof(String), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(XElement), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanWrite(typeof(XElement), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanWrite(typeof(String), new MediaType("application", "xml")));
}
[Test]
@@ -110,12 +110,8 @@ namespace Spring.Http.Converters.Xml
converter.Write(body, null, webRequest);
requestStream.Position = 0;
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
Assert.AreEqual(body.ToString(SaveOptions.DisableFormatting), result, "Invalid result");
}
byte[] result = requestStream.ToArray();
Assert.AreEqual(body.ToString(SaveOptions.DisableFormatting), Encoding.UTF8.GetString(result), "Invalid result");
mocks.VerifyAll();
}

View File

@@ -61,9 +61,9 @@ namespace Spring.Http.Converters.Xml
{
Assert.IsTrue(converter.CanWrite(typeof(XmlDocument), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(XmlDocument), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanRead(typeof(XmlDocument), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanRead(typeof(XmlDocument), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanRead(typeof(String), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(XmlDocument), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanWrite(typeof(XmlDocument), new MediaType("text", "plain")));
Assert.IsFalse(converter.CanWrite(typeof(String), new MediaType("application", "xml")));
}
[Test]
@@ -102,14 +102,10 @@ namespace Spring.Http.Converters.Xml
mocks.ReplayAll();
converter.Write(body, null, webRequest);
converter.Write(body, null, webRequest);
requestStream.Position = 0;
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
Assert.AreEqual(body.OuterXml, result, "Invalid result");
}
byte[] result = requestStream.ToArray();
Assert.AreEqual(body.OuterXml, Encoding.UTF8.GetString(result), "Invalid result");
mocks.VerifyAll();
}

View File

@@ -57,10 +57,10 @@ namespace Spring.Http.Converters.Xml
[Test]
public void CanWrite()
{
Assert.IsTrue(converter.CanRead(typeof(CustomClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanRead(typeof(CustomClass), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanRead(typeof(CustomClass), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanRead(typeof(CustomClass), new MediaType("text", "plain")));
Assert.IsTrue(converter.CanWrite(typeof(CustomClass), new MediaType("application", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(CustomClass), new MediaType("text", "xml")));
Assert.IsTrue(converter.CanWrite(typeof(CustomClass), new MediaType("application", "soap+xml"))); // application/*+xml
Assert.IsFalse(converter.CanWrite(typeof(CustomClass), new MediaType("text", "plain")));
}
[Test]
@@ -102,12 +102,8 @@ namespace Spring.Http.Converters.Xml
converter.Write(body, null, webRequest);
requestStream.Position = 0;
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
Assert.AreEqual(expectedBody, result, "Invalid result");
}
byte[] result = requestStream.ToArray();
Assert.AreEqual(expectedBody, Encoding.UTF8.GetString(result), "Invalid result");
mocks.VerifyAll();
}

View File

@@ -28,9 +28,6 @@ using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Channels;
using Spring.Http;
using Spring.Http.Rest.Support;
using NUnit.Framework;
namespace Spring.Http.Rest
@@ -243,98 +240,6 @@ namespace Spring.Http.Rest
template.Execute<object>("servererror", null, null);
}
//@BeforeClass
//public static void startJettyServer() throws Exception {
// jettyServer = new Server(8889);
// Context jettyContext = new Context(jettyServer, "/");
// byte[] bytes = helloWorld.getBytes("UTF-8");
// contentType = new MediaType("text", "plain", Collections.singletonMap("charset", "utf-8"));
// jettyContext.addServlet(new ServletHolder(new GetServlet(bytes, contentType)), "/get");
// jettyContext.addServlet(new ServletHolder(new GetServlet(new byte[0], contentType)), "/get/nothing");
// jettyContext.addServlet(
// new ServletHolder(new PostServlet(helloWorld, URI + "/post/1", bytes, contentType)),
// "/post");
// jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
// jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
// jettyContext.addServlet(new ServletHolder(new UriServlet()), "/uri/*");
// jettyContext.addServlet(new ServletHolder(new MultipartServlet()), "/multipart");
// jettyServer.start();
//}
//@Test
//public void uri() throws InterruptedException, URISyntaxException {
// String result = template.getForObject(URI + "/uri/{query}", String.class, "Z\u00fcrich");
// Assert.AreEqual("Invalid request URI", "/uri/Z%C3%BCrich", result);
// result = template.getForObject(URI + "/uri/query={query}", String.class, "foo@bar");
// Assert.AreEqual("Invalid request URI", "/uri/query=foo@bar", result);
// result = template.getForObject(URI + "/uri/query={query}", String.class, "T\u014dky\u014d");
// Assert.AreEqual("Invalid request URI", "/uri/query=T%C5%8Dky%C5%8D", result);
//}
//@Test
//public void multipart() throws UnsupportedEncodingException {
// MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
// parts.add("name 1", "value 1");
// parts.add("name 2", "value 2+1");
// parts.add("name 2", "value 2+2");
// Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");
// parts.add("logo", logo);
// template.postForLocation(URI + "/multipart", parts);
//}
//private static class UriServlet extends HttpServlet {
// @Override
// protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setContentType("text/plain");
// resp.setCharacterEncoding("UTF-8");
// resp.getWriter().write(req.getRequestURI());
// }
//}
//private static class MultipartServlet extends HttpServlet {
// @Override
// protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// assertTrue(ServletFileUpload.isMultipartContent(req));
// FileItemFactory factory = new DiskFileItemFactory();
// ServletFileUpload upload = new ServletFileUpload(factory);
// try {
// List items = upload.parseRequest(req);
// Assert.AreEqual(4, items.size());
// FileItem item = (FileItem) items.get(0);
// assertTrue(item.isFormField());
// Assert.AreEqual("name 1", item.getFieldName());
// Assert.AreEqual("value 1", item.getString());
// item = (FileItem) items.get(1);
// assertTrue(item.isFormField());
// Assert.AreEqual("name 2", item.getFieldName());
// Assert.AreEqual("value 2+1", item.getString());
// item = (FileItem) items.get(2);
// assertTrue(item.isFormField());
// Assert.AreEqual("name 2", item.getFieldName());
// Assert.AreEqual("value 2+2", item.getString());
// item = (FileItem) items.get(3);
// Assert.IsFalse(item.isFormField());
// Assert.AreEqual("logo", item.getFieldName());
// Assert.AreEqual("logo.jpg", item.getName());
// Assert.AreEqual("image/jpeg", item.getContentType());
// }
// catch (FileUploadException ex) {
// throw new ServletException(ex);
// }
// }
//}
#region REST test service
[ServiceContract]

View File

@@ -22,7 +22,6 @@ using System;
using System.Net;
using System.Collections.Generic;
using Spring.Http;
using Spring.Http.Converters;
using NUnit.Framework;

View File

@@ -107,6 +107,7 @@
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Http\Converters\ByteArrayHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\UrlEncodedFormHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\Feed\Atom10FeedHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\Feed\FeedHttpMessageConverterIntegrationTests.cs" />
<Compile Include="Http\Converters\Feed\Rss20FeedHttpMessageConverterTests.cs" />

View File

@@ -128,6 +128,7 @@
<Compile Include="Http\Converters\Json\JsonHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\Json\JsonHttpMessageConverterIntegrationTests.cs" />
<Compile Include="Http\Converters\StringHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\UrlEncodedFormHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\Xml\XmlHttpMessageConverterIntegrationTests.cs" />
<Compile Include="Http\Converters\Xml\XElementHttpMessageConverterTests.cs" />
<Compile Include="Http\Converters\Xml\XmlSerializableHttpMessageConverterTests.cs" />