我正在WCF 4.0中开发一些RESTful服务.我有一个方法如下:
[OperationContract]
[WebGet(UriTemplate = "Test?format=XML&records={records}", ResponseFormat=WebMessageFormat.Xml)]
public string TestXml(string records)
{
return "Hello XML";
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我将浏览器导航到http:// localhost:8000/Service/Test?format = XML&records = 10,那么一切都可以正常运行.
但是,我希望能够导航到http:// localhost:8000/Service/Test?format = XML并且不使用URL的"&records = 10"部分.但是现在,我收到服务错误,因为URI与预期的URI模板不匹配.
那么如何为我的一些查询字符串参数实现默认值呢?我希望将"记录"默认为10,例如,如果该部分不在查询字符串中.
我有一些我正在写的Web服务,我想尽可能地保持RESTful.我使用在IIS/ASP.NET/SharePoint中运行的HTTPHandler来托管这些Web服务.
我的大多数服务都期望HTTP GET.我有两个只是返回一些数据(即查询)并将是幂等的,但参数可能有点复杂.它们都可以包括服务参数中的字符,这些字符至少不允许URL的PATH部分.
使用IIS,ASP.NET和SharePoint我发现URL路径中的以下字符甚至没有进入我的HttpHandler,即使Url编码(请求爆炸,我对此没有任何简单的控制) :
(%3E)
以下字符使其成为我的HttpHandler,但即使Url编码,UriTemplate也无法正确处理它们:
所以,我有点彻底,但我需要在查询字符串中测试这些url编码的字符.看起来这在大多数情况下都会起作用.
在我的一个服务中,作为参数的特殊字符在语义上是查询/过滤器的一部分(实际上是搜索服务的搜索项),但在另一个中它们实际上不是查询/过滤器的一部分,所以理想情况下它们是路径而不是查询字符串.
我的问题是,最好的选择是什么?以下是我所知道的一些内容:
使用HTTP GET和查询字符串. 任何可能使用特殊字符的内容都应该在查询字符串和Url Encoded上. 这是我倾向于的地方,但我担心极长的查询字符串(IE有2083限制)
在路径中使用HTTP GET和base64编码.对于可能使用特殊字符的任何参数, 请使用Modified Base64 for URL,并将其作为路径的一部分(如果需要). 我试过这个并且它有效,但它有点难看.关于极长查询字符串的问题仍然存在.
使用HTTP POST和邮件正文. 任何可能使用特殊字符的东西都应该在请求的正文中. 似乎是一个不错的解决方案,但帖子被理解为不被幂和(我认为)通常意味着更改(而没有变化发生在这里).
使用HTTP GET和邮件正文. 任何可能使用特殊字符的东西都应该在请求的正文中.根据SO,这似乎是一个坏主意:请求正文和Roy Fielding的HTTP GET.
根据请求的大小,使用#3和#1或#2的组合.
其他???
请注意,在某些情况下,我可以更改周围的东西以防止特殊字符(我可能会这样做),但我无法在所有情况下都这样做.
关于URI长度,RFC2616 Sec3.2.1说明如下:
HTTP协议不对URI的长度设置任何先验限制.服务器必须能够处理它们所服务的任何资源的URI,并且如果它们提供可以生成这种URI的基于GET的表单,它应该能够处理无限长度的URI.如果URI长于服务器可以处理的长度,服务器应该返回414(Request-URI Too Long)状态(参见10.4.15节).
Note: Servers ought to be cautious about depending on …Run Code Online (Sandbox Code Playgroud) 我正在使用WCF 4.0来创建REST-ful Web服务.我想要做的是根据查询字符串参数调用不同的服务方法UriTemplate.
例如,我有一个API,允许用户使用其驾驶执照或社会安全号码作为密钥来检索有关某人的信息.在我的ServiceContract/ interface中,我将定义两个方法:
[OperationContract]
[WebGet(UriTemplate = "people?driversLicense={driversLicense}")]
string GetPersonByLicense(string driversLicense);
[OperationContract]
[WebGet(UriTemplate = "people?ssn={ssn}")]
string GetPersonBySSN(string ssn);
Run Code Online (Sandbox Code Playgroud)
但是,当我使用这两种方法调用我的服务时,我得到以下异常:
UriTemplateTable不支持具有与模板'people?ssn = {ssn}'等效路径的多个模板,但具有不同的查询字符串,其中查询字符串不能通过文字值消除歧义.有关更多详细信息,请参阅UriTemplateTable的文档.
有没有办法做到这一点UriTemplates?这似乎是一种常见的情况.
非常感谢!
我正在使用节点和表达.要注册控制器我打电话:
app.get('/user/:id', function (req, res) {...});
Run Code Online (Sandbox Code Playgroud)
但我想用rfc-6570方式做到这一点:
app.get('/user/{id}', function (req, res) {...});
Run Code Online (Sandbox Code Playgroud)
我在谷歌代码上搜索了python中的一个实现,但没有找到任何内容(除了谷歌代码上的死链接到http://www.snellspace.com/wp/?p=831).
一般来说,URI模板并不像第一眼看上去那么容易.看看RFC中的示例.
PS:我也需要客户端上的URI模板.
我有以下映射:
@RequestMapping(value = "/{first}/**/{last}", method = RequestMethod.GET)
public String test(@PathVariable("first") String first, @PathVariable("last")
String last) {}
Run Code Online (Sandbox Code Playgroud)
对于以下URI:
foo/a/b/c/d/e/f/g/h/bar
foo/a/bar
foo/bar
Run Code Online (Sandbox Code Playgroud)
将foo映射到第一个,将bar映射到最后并且工作正常.
我想要的是将foo和bar之间的所有内容映射到单个路径参数,或者如果没有中间(如在上一个URI示例中),则为null:
@RequestMapping(value = "/{first}/{middle:[some regex here?]}/{last}",
method = RequestMethod.GET)
public String test(@PathVariable("first") String first, @PathVariable("middle")
String middle, @PathVariable("last") String last) {}
Run Code Online (Sandbox Code Playgroud)
因为我希望像{middle:.*}那样简单,只能映射到/ foo/a/bar,或者{middle:(.*/)*},这似乎没有映射到正则表达式.
在应用正则表达式模式之前,AntPathStringMatcher是否在"/"上进行标记?(制作跨越/不可能的模式)还是有解决方案?
仅供参考,这是在春季3.1M2
这看起来类似于@RequestMapping控制器和动态URL,但我没有看到解决方案.
是否有Java独立实现来提取URI中模板(RFC 6570)定义的参数值?
我发现的最佳实现是ruby实现(https://github.com/sporkmonger/addressable)
通过http://code.google.com/p/uri-templates/wiki/Implementations我找到了一个Java实现:Handy-URI-Templates
它支持使用参数值解析URI模板到最终URI.不幸的是,它无法做到相反:根据URI-Template提取URI中的参数值.
JAX-RS(或Restlet)的实现在内部具有此功能.但是似乎没有一个孤立的这个功能模块可以独立使用.
有没有人有另一个想法?
这里有一个使用spring-Web的例子:
import org.springframework.web.util.UriTemplate;
public class UriParserSpringImpl implements UriParser {
private final UriTemplate uriTemplate;
private final String uriTemplateStr;
public UriParserSpringImpl(final String template) {
this.uriTemplateStr = template;
this.uriTemplate = new UriTemplate(template);
}
@Override
public Map<String, String> parse(final String uri) {
final boolean match = this.uriTemplate.matches(uri);
if (!match) {
return null;
}
return uriUtils.decodeParams(this.uriTemplate.match(uri));
}
@Override
public Set<String> getVariables() {
return Collections.unmodifiableSet(new LinkedHashSet<String>(this.uriTemplate.getVariableNames()));
}
}
Run Code Online (Sandbox Code Playgroud)
Jersey的另一个(JAX-RS实现):
import com.sun.jersey.api.uri.UriTemplate;
public class UriParserJerseyImpl implements …Run Code Online (Sandbox Code Playgroud) 像ASP.NET或Nancy这样的框架提供了可用于指定路由的语法,例如:
MapRoute("/customers/{id}/invoices/{invoiceId}", ...)
Run Code Online (Sandbox Code Playgroud)
在ASP.NET中,路由工作在两个方向.它们可以匹配请求URI(例如 /customers/32/invoices/19路由),并且可以将参数解析为{ id: 37, invoiceId: 19 }URI.
RFC 6570:URI模板还定义了一个类似的,虽然更丰富的URI规范,通常用于解析 URI.例如:
UriTemplate("/customers/{id}/invoices{/invoiceId}{?sort}", { id: 37, invoiceId: 19, sort: 'asc' } )
// returns: /customers/37/invoices/19?sort=asc
Run Code Online (Sandbox Code Playgroud)
我的问题是,RFC 6570中指定的语法是否可用于将请求URI与路由匹配?是否有一部分语法会使给定的URI与给定的URI模板匹配变得模糊不清?是否有任何库支持将URI与URI模板匹配?
在我的RESTful WCF Serice中,我需要传递一个类作为URITemplate的参数.我能够传递一个字符串或多个字符串作为参数.但是我有很多字段可以传递给WCF服务.所以我创建了一个类并将所有字段添加为属性,然后我想将此类作为一个参数传递给URITemplate.当我试图将类传递给URITemplate时,我收到错误"路径段必须有类型字符串".它不接受类作为参数.知道如何将类作为参数传递.这是我的代码(inputData是类)
[OperationContract]
[WebGet(UriTemplate = "/InsertData/{param1}")]
string saveData(inputData param1);
Run Code Online (Sandbox Code Playgroud) [OperationContract]
[WebGet(UriTemplate = "/searchresults/{searchTerm}/{searchType}", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
Message GetSearchResults(string searchTerm, string searchType);
[OperationContract]
[WebGet(UriTemplate = "/searchresults/{searchTerm}", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
Message GetSearchResults(string searchTerm);
Run Code Online (Sandbox Code Playgroud)
这是否可能 - 如果没有,有人可以提出替代方案吗?
假设我正在使用新的WCF Web API来构建RESTful服务,并且在我的服务中,我有一段描述目标资源的URI,但用于(几乎)合同的所有方法.例如,如果我有一个处理电子商务的用户服务,可能看起来像:
[ServiceContract]
public class MyUserService
{
private MyUserRepository _UserRepo;
private MyOrganizationRepository _OrgRepo;
[WebGet (UriTemplate = "{OrganizationName}/Users")]
public IEnumerable<User> GetUsers (string OrganizationName)
{
IEnumerable<User> Users = null;
var Organization = _OrgRepo.GetOrgByName (OrganizationName);
if (Organization != null)
{
Users = Organization.GetUsers ();
}
else
{
throw new WebFaultException<string> ("Organization not found.", HttpStatusCode.NotFound);
}
return Users;
}
[WebInvoke (UriTemplate = "{OrganizationName}/Users", /*yada...yada...yada*/)]
public User AddNewUser (string OrganizationName, User User)
{
// Find the organization, like above, and throw if null.
} …Run Code Online (Sandbox Code Playgroud) uritemplate ×10
wcf ×5
rest ×3
java ×2
asp.net ×1
asp.net-mvc ×1
c# ×1
dry ×1
express ×1
get ×1
http ×1
javascript ×1
jax-rs ×1
node.js ×1
parsing ×1
query-string ×1
regex ×1
restlet ×1
routing ×1
service ×1
spring-mvc ×1
uri ×1
wcf-web-api ×1