我正在使用Drupal服务和REST服务器来提供API 以前我只使用一种类型的响应JSON,所以我不需要额外的扩展名“.json”到URL。
现在我必须添加新的格式化程序,XML 然后问题开始,所有没有任何扩展名的API(.json或.xml)都将默认输出设置为XML。
我试着追踪这个问题,最后发现相关变量是'rest_server_default_response_format'。
服务模块上的相关代码是getResponseFormatContentTypeNegotiations
所以我有$ mime_candidates []值
Array ( [0] => application/xml [1] => text/xml [2] => application/json )
甚至在第87行已经将response_format设置为json, 但是mimeparse-> best_match()返回'text / xml'。
最好的方法是什么呢?
我不认为编辑getResponseFormatContentTypeNegotiations是最好的方法
无论如何要使best_match函数更喜欢格式JSON而不是XML?
答案 0 :(得分:1)
最好的方法是在您的请求中使用“接受”标题:
String s2="foo";
String s6="bar";
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");
String query="update mydb set Status='"+s6+"' where IC_Number='"+s2+"'";
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(query);
con.close();
}
catch(Exception e)
{
System.out.println("Error in login:"+e);
}
}
}
如果json可用,它将用作响应而不是xml。
答案 1 :(得分:1)
通过管理界面,您可以修改已配置的服务,仅返回某些格式。
结构>服务
然后编辑资源>服务器选项卡
然后您可以选择响应格式并将其专门设为json。
答案 2 :(得分:1)
在最新版本的服务中,所有操作都发生在getResponseFormatContentTypeNegotiations()
文件的services/servers/rest_server/includes/ServicesContentTypeNegotiator.inc
中;具体来说,这部分:
// Get the best matching format, default to json
$response_format = variable_get('rest_server_default_response_format', 'json');
$http_accept = $context->getServerVariable('HTTP_ACCEPT');
if (!empty($http_accept)) {
$mime = $this->mimeParse();
$mime_type = $mime->best_match($mime_candidates, $http_accept);
$response_format = isset($mime_map[$mime_type]) ? $mime_map[$mime_type] : '';
}
正在发生的事情是它获得了JSON格式化程序的默认值。然后,它会查看您的请求的接受标头。如果您的接受标头没有指定有效的MIME类型,那么它将使用JSON。
似乎所有现代浏览器都有此功能称为' content negotiation',默认情况下,它们主要指定它们首先接受HTML,然后是XML(尽管这会因浏览器而异)。
因此,考虑到这一点,您希望客户端只需要从其请求标头中删除XML mimetypes以获取JSON。不是那么不幸。
如果请求包含任何'接受'首先,代码会尝试将标题与您已启用的解析器列表相匹配(让我们说它只是XML,JSON),它会选择匹配的解析器,或者第一个。因此,如果您确实有接受标头并且未指定有效的MIME类型,服务将使用您已启用的第一个。
要更改已启用的解析器的顺序,我认为您可以使用services.alter.api.php
中的一个挂钩。