How can I get GWT RequestFactory to with in a Gadget?
Getting GWT-RPC to work with Gadgets is explained here.
I'm looking for a analogous solution for RequestFactory.
I tried using the GadgetsRequestBuilder, so far I've managed to get the request to the server using:
requestFactory.initialize(eventBus, new DefaultRequestTransport() {
#Override
protected RequestBuilder createRequestBuilder() {
return new GadgetsRequestBuilder(RequestBuilder.POST,
getRequestUrl());
}
#Override
public String getRequestUrl() {
return "http://....com/gadgetRequest";
}
});
But I end up with the following error:
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:694)
at com.google.gwt.autobean.server.impl.JsonSplittable.create(JsonSplittable.java:35)
at com.google.gwt.autobean.shared.impl.StringQuoter.split(StringQuoter.java:35)
at com.google.gwt.autobean.shared.AutoBeanCodex.decode(AutoBeanCodex.java:520)
at com.google.gwt.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:121)
The general approach for sending a RequestFactory payload should be the same as RPC. You can see the payload that's being received by the server by running it with the JVM flag -Dgwt.rpc.dumpPayload=true. My guess here is that the server is receiving a request with a zero-length payload. What happens if you set up a simple test involving a GadgetsRequestBuilder sending a POST request to your server? Do you still get the same zero-length payload behavior?
Related
I have the following stream.
Context of the problem
1.
rabbit --password='******' --queues=springdataflow-q --virtual-host=springdataflow --host=172.24.172.184 --username=springdataflow | transform | httpclient --url-expression='http://172.20.24.47:8080/push' --http-method=POST --headers-expression={'Content-Type':'application/x-www-form-urlencoded'} --body-expression={arg1:payload} | log
2.
I have spring boot running locally.
#RestController
public class HelloController {
#RequestMapping(value = "/push", method = RequestMethod.POST,produces = {MediaType.TEXT_PLAIN})
public String pushMessage(#RequestParam(value="arg1") String payload) {
System.out.println(payload);
return payload;
}
}
I would like to have the rabbit message come into httpclient as value for the the 'arg1' parameter value to the post request. The intent being that message published on rabbit queue is consumed by a rest post point, the message being captured by SpEL payload.
For this I am using the body-expression = {arg1:payload} but this is not working, maybe syntactically wrong.
Any suggestions ?
The #RequestParam(value="arg1") is really about request param, the part of the URL after ?, which is called query string: https://en.wikipedia.org/wiki/Query_string.
So, if you really would like to have an arg1=payload pair in the query string, you need to use a proper url-expression:
--url-expression='http://172.20.24.47:8080/push?arg1='+payload
This seems to work to pass strings as payloads. It seems that by default the payload becomes requestbody.
So on the rest service I made a change:
#RequestMapping(value = "/pushbody", method = RequestMethod.POST,consumes = {MediaType.TEXT_PLAIN})
public String pushBody(#RequestBody String payload) {
System.out.println(payload);
return payload;
}
And the stream that seems to work now is :
rabbit --password='******' --queues=springdataflow-q1 --host=172.24.172.184 --virtual-host=springdataflow --username=springdataflow | httpclient --http-method=POST --headers-expression={'Content-Type':'text/plain'} --url=http://172.20.24.47:8080/pushbody | log
I did try with inputType= text/plain suggestion both on httpclient and logsink and removing the consumes and produces on the rest service post method, but no luck there.
I created a simple project which using CookieJar. Now I am trying to understand when saveFromResponse method works. But I see in my logs that loadForRequest works fine, but I doesn't see saveFromResponse logs. Why? At what time of process this method works? Can we use only intercept method if we works with cookies or may be we have a special situation for using CookieJar?
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new ReceivedCookiesInterceptor())
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
#Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
Log.d(TAG,"saveFromResponse");
cookieStore.put(url, cookies);
}
#Override
public List<Cookie> loadForRequest(HttpUrl url) {
Log.d(TAG,"loadForRequest");
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
response.body().close();
I know it's a bit late, but I was struggling with the exact same issue and then I realised that saveFromResponse is only called on new cookies. This means that all the cookies you set on loadForRequest are not received in saveFromResponse.
That's the behaviour I could infer, but I'm not sure if it is the one that it should be, as this way you can't get cookie value updates from remote server.
Did you experienced the behaviour that only on the first request after OkHttpClient creation the cookies are received and not on the rest of the requests?
Please, someone with more knowledge that can shed some light?
I'm using Volley to send an http post request with parameters from my android app to my local server running in http://192.168.1.4:3000/battery_signal_report
I'm pretty sure the server is running properly (I checked it with Postman successfully).
also, I successfully sent the request through Android Studio's Emulator using ip 10.0.2.2
Trying to make it work, i used various request implementations including JsonObjectRequest, StringRequest and the custom request described here: Volley JsonObjectRequest Post request not working
Also, I've read somewhere that Volley post requests have some problems with the request header, so i tried to override it in different ways.
Nothing works. onErrorResponse is called every time with an empty VolleyError input.
I've fairly new to android development, so any insights would be much appreciated.
Thanks in advance.
For anyone else coming across this, you need to forget about the header override and setup your own getBodyContentType() and getBody() methods. Follow this pattern:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, successListener, errorListener) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";//set here instead
}
#Override
public byte[] getBody() {
try {
Map<String, String> params = yourObject.getMappedParams();
JSONObject json = new JSONObject(params);
String requestBody = json.toString();
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
return null;
}
}
};
I have set expectedResponseType(MyClass.class). So OutboundGateway is converting the message into my response class type and returning to me. I want to log the payload as well for debugging purpose along with the conversion.
How to do this response payload logging and conversion.?
I could do it by expecting the response as String and later convert into my class using marshallers. Is there any simpler way that can be used for all my outbound gateways?
The expectedResponseType(MyClass.class) is translated to the
httpResponse = this.restTemplate.exchange(realUri, httpMethod, httpRequest, (Class<?>) expectedResponseType);
where the last one does this:
public ResponseEntityResponseExtractor(Type responseType) {
if (responseType != null && Void.class != responseType) {
this.delegate = new HttpMessageConverterExtractor<T>(responseType,
getMessageConverters(), logger);
}
else {
this.delegate = null;
}
}
As you see it is copying its own logger to the HttpMessageConverterExtractor.
So, I think you can achieve some good result for your logging requirements switching on DEBUG (or even TRACE) for the org.springframework.web.client.RestTemplate category.
From other side you always can extend the RestTemplate a bit to make some hooks into it.
From the Spring Integration perspective we can do nothing. Because the whole hard conversion work is done in the RestTemplate.
I'd like to be able to requeue a message from within my Service Endpoint that has been wired up through the RegisterHandler method of RabbitMQ Server. e.g.
mqServer.RegisterHandler<OutboundILeadPhone>(m =>
{
var db = container.Resolve<IFrontEndRepository>();
db.SaveMessage(m as Message);
return ServiceController.ExecuteMessage(m);
}, noOfThreads: 1);
or here.
public object Post(OutboundILeadPhone request)
{
throw new OutBoundAgentNotFoundException(); // added after mythz posted his first response
}
I don't see any examples how this is accomplished, so I'm starting to believe that it may not be possible with the ServiceStack abstraction. On the other hand, this looks promising.
Thank you, Stephen
Update
Throwing an exception in the Service does nak it, but then the message is sent to the OutboundILeadPhone.dlq which is normal ServiceStack behavior. Guess what I'm looking for is a way for the message to stay in the OutboundILeadPhone.inq queue.
Throwing an exception in your Service will automatically Nak the message. This default exception handling behavior can also be overridden with RabbitMqServer's RegisterHandler API that takes an Exception callback, i.e:
void RegisterHandler<T>(
Func<IMessage<T>, object> processMessageFn,
Action<IMessage<T>, Exception> processExceptionEx);
void RegisterHandler<T>(
Func<IMessage<T>, object> processMessageFn,
Action<IMessage<T>, Exception> processExceptionEx,
int noOfThreads)