我正在尝试让GWT + RESTlet与RESTful服务进行通信,而不是“GWT感知”。
在GWT客户端上,我执行类似
的操作Reference ref = new Reference("http://localhost:8080/control/programs/");
ProgramListResourceProxy clientResource = GWT.create( ProgramListResourceProxy.class );
clientResource.setReference( proxyRef );
clientResource.setFollowingRedirects( true );
clientResource.accept( MediaType.APPLICATION_JSON );
clientResource.accept( MediaType.APPLICATION_XML );
ProgramListResourceProxy resource = RestClient.createProgramListResource();
resource.retrieve( new Result<ArrayList<ProgramRef>>()
{
@Override
public void onFailure( Throwable caught )
{
while( caught != null)
{
Window.alert( "Error retrieving programs.\n" + caught.getMessage() );
caught = caught.getCause();
}
}
@Override
public void onSuccess( ArrayList<ProgramRef> result )
{
Window.alert( "Programs: " + result );
programs = result;
view.setRowData( toStringList( result ) );
}
});
如果我从浏览器请求资源,我会
[{"name":"niclas","link":{"action":"GET","path":"/control/programs/niclas/"}}]
正如所料。
但是当在GWT中执行上面的代码时,我得到弹出警告告诉我存在问题,并且在嵌套异常中是;
Error retrieving programs.
Can't parse the enclosed entity because of its media type.
Expected <application/x-java-serialized-object+gwt> but was
<application/json>. Make sure you have added the
org.restlet.client.ext.gwt.jar file to your server.
MediaTypes在请求/响应中匹配,流量如下所示。
请求;
GET /control/programs/ HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, application/xml
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Referer: http://localhost:8080/connect/Connect.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
响应;
HTTP/1.1 200 OK
Date: Sat, 30 Mar 2013 15:46:04 GMT
Content-Type: application/json; charset=UTF-8
Date: Sat, 30 Mar 2013 15:46:04 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.1.2
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Transfer-Encoding: chunked
4E
[{"name":"niclas","link":{"method":"GET","path":"/control/programs/niclas/"}}]
有人可以解释为什么Restlet期望“application / x-java-serialized-object + gwt”而不是资源中设置的MediaType吗?
是否与使用org.restlet.client.resource.ClientProxy有关?如果是这样,是否有另一种方法可以使用RESTlet执行这些异步请求?
我正在使用RESTlet 2.1.2和GWT 2.2.0。
先谢谢。
答案 0 :(得分:0)
我通常使用带有覆盖类型的JsonpRequestBuilder(在本例中为JsonVideoList):
JsonpRequestBuilder builder = new JsonpRequestBuilder();
builder.requestObject(url, new AsyncCallback<JsonVideoList>() {
@Override
public void onFailure( Throwable exception) {
}
@Override
public void onSuccess(JsonVideoList list) {
}
});
答案 1 :(得分:0)
我发现this issue在谷歌中搜索您的问题,这可能已经连接。
以下内容可能效率不高,但您也可以查看restyGWT进行休息调用。
答案 2 :(得分:0)
当天结束时有几个问题,我认为我最好分享我的发现;
我没有意识到我有一个“同源”的问题。这是通过在我的Rest服务器的GWT服务端口上使用透明代理来解决的。这似乎也正确地将Rest服务器的身份验证转发到浏览器中的GWT应用程序。
Restlet在Editions中的包装似乎是一个非常好的主意。但是让IntelliJ IDEA能够使用这些以及共享的DTO模块来设置GWT调试环境真的很困难。我认为我有其他问题有关Restlet的方法,以确定使用哪些内容类型和不使用的内容类型。当天结束时,我说服自己不要打扰共享的DTO库而是;
AutoBean很棒;
public interface Program
{
String getName();
void setName( String name );
List<Block> getBlocks();
void setBlocks(List<Block> blocks);
List<Connection> getConnections();
void setConnections(List<Connection> connections );
public static class Factory
{
public static Program make() {
AutoBean<Program> ref = ModelFactory.instance.program();
return ref.as();
}
public static String toJson(Program ref) {
AutoBean<Program> bean = AutoBeanUtils.getAutoBean( ref );
return AutoBeanCodex.encode( bean ).getPayload();
}
public static Program fromJson(String json) {
AutoBean<Program> bean = AutoBeanCodex.decode( ModelFactory.instance, Program.class, json );
return bean.as();
}
}
}
为了使样本完整,我的ModelFactory有这些的创建方法,这些方法也由GWT完全处理;
public interface ModelFactory extends AutoBeanFactory
{
ModelFactory instance = GWT.create( ModelFactory.class );
AutoBean<Program> program();
AutoBean<ProgramRefList> programRefList();
:
}
一个不明显的问题是如何处理顶级JSON列表,因为AutoBean将JSON键与接口中的字段匹配。但我找到了一个巧妙的小技巧,可以在同一个程序的以下片段中看到;
public interface ProgramRefList
{
List<ProgramRef> getList();
public static class Factory
{
public static ProgramRefList make()
{
AutoBean<ProgramRefList> ref = ModelFactory.instance.programRefList();
return ref.as();
}
public static String toJson( ProgramRefList ref )
{
AutoBean<ProgramRefList> bean = AutoBeanUtils.getAutoBean( ref );
return AutoBeanCodex.encode( bean ).getPayload();
}
public static ProgramRefList fromJson( String json )
{
json = "{ \"list\": " + json + "}";
AutoBean<ProgramRefList> bean = AutoBeanCodex.decode( ModelFactory.instance, ProgramRefList.class, json );
return bean.as();
}
}
}
顶级列表伪造成另一个具有单个键的对象(在本例中为“list”),然后可以从getList()方法访问它。
然后在Rest客户端代码中使用它非常简单;
ClientResource resource = RestClient.createProgramList( new Uniform()
{
@Override
public void handle( Request request, Response response )
{
Logger.trace( this, "handle(" + request + "," + response + ")" );
try
{
if( response.isEntityAvailable() )
{
String jsonText = response.getEntity().getText();
programs = ProgramRefList.Factory.fromJson( jsonText );
ArrayList<String> rowData = toStringList( programs );
view.setRowData( rowData );
}
}
catch( Exception e )
{
Logger.handleException( this, "loadProgramsList()", e );
}
}
} );
resource.get();