How to form Html response from play.mvc.Results.redirect("/auth/authenticate/facebook") call? - playframework-2.3

Here I do redirect call to Facebook login page that returns as 'play.mvc.Result' Object but I require as 'play.twirl.api.Html'
public class SecureSocialTemplatesPlugin implements ViewTemplates {
#Override
public Html getLoginPage(Form<Tuple2<String, String>> arg0, Option<String> arg1, RequestHeader arg2, Lang arg3) {
play.mvc.Results.redirect("/auth/authenticate/facebook");//Issue here is this call returns play.mvc.Result object but I require Html
return sociallogin.render(socialSite);
}
}
How to generate html response from redirect call response?

You are doing it wrong, you should return the Result (as for every Play action - actually redirect(...) is Result too), so it should be:
public Html getLoginPage(Form<Tuple2<String, String>> arg0, Option<String> arg1, RequestHeader arg2, Lang arg3) {
// ...
return play.mvc.Results.redirect("/auth/authenticate/facebook");
}

Related

custom hamcrest matcher succeeds but the test fails

I have this custom matcher:
public class CofmanStringMatcher extends TypeSafeMatcher<String> {
private List<String> options;
private CofmanStringMatcher(final List<String> options) {
this.options = Lists.newArrayList(options);
}
#Override
protected boolean matchesSafely(final String sentResult) {
return options.stream().anyMatch(option -> option.equals(sentResult));
}
public static CofmanStringMatcher isCofmanStringOnOfTheStrings(List<String> options) {
return new CofmanStringMatcher(options);
}
#Override
public void describeTo(final Description description) {
System.out.println("in describeTo");
// description.appendText("expected to be equal to of the list: "+options);
}
}
which compares a string to few options for strings.
when i run this test code:
verify(cofmanService, times(1))
.updateStgConfigAfterSimulation(argThat(isCofmanStringOnOfTheStrings(ImmutableList.of(expectedConditionsStrings , expectedConditionsStrings2))), eq(Constants.addCommitMsg+SOME_REQUEST_ID));
I get this error:
Comparison Failure: <Click to see difference>
Argument(s) are different! Wanted:
cofmanService.updateStgConfigAfterSimulation(
,
"add partner request id = 1234"
);
-> at com.waze.sdkService.services.pubsub.callback.RequestToCofmanSenderTest.localAndRtValidationSucceeds_deployCofmanStg(RequestToCofmanSenderTest.java:131)
Actual invocation has different arguments:
cofmanService.updateStgConfigAfterSimulation(
"some text"
);
The test fails even though the method updateStgConfigAfterSimulation calls with 1st arg that matches on of the list elements
I'm using
mockito 1.10 and hamcrest 1.3
here is the method's signature
void updateStgConfigAfterSimulation(String conditionsMap, String commitMsg) throws Exception

Apache Camel JSON Marshalling to POJO Java Bean

I think I have a simple question, but can't seem to figure it out.
I'm invoking a POJO with a class created from unmarshalling JSON as the parameter for the method. The question is, how do I marshal the return from the method back to JSON?
My route is below;
from("direct:start")
.choice()
.when(header("methodname").isEqualTo("listCases"))
.unmarshal().json(JsonLibrary.Jackson, UserDetails.class)
.to("bean:com.xxx.BeanA")
.when(header("methodName").isEqualTo("listPersons"))
.unmarshal().json(JsonLibrary.Jackson, CaseDetails.class)
.to("bean:com.xxx.BeanB");
...and I'm invoking the route by the below;
ProducerTemplate template = camelContext.createProducerTemplate();
template.setDefaultEndpoint(camelContext.getEndpoint("direct:start"));
InvocationResult result = (InvocationResult)template.requestBodyAndHeader(payload, "methodName", methodName);
Payload is JSON, and the methodName is either listCases or listPersons in this example.
My InvocationResult class is generic and contains a String returnCode attribute as well as an object reference to the object I would like to be converted to JSON. This object will be different depending on whether listCases or listPersons is executed.
Thanks,
Bic
My impression is that your actual issue isn't about marshalling (which should be entirely straightforward), but about processing a response after having routed the message using choice(). You need to close the choice() block using end() (assuming the result of each branch will be processed in the same way), then make sure the response gets written to the out message body in the last step of the route.
Anyway, here is an example I've just tested:
public class JacksonTestRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("jetty:http://localhost:8181/foo").to("direct:foo");
from("direct:foo")
.unmarshal().json(JsonLibrary.Jackson, Foo.class)
.choice()
.when().simple("${body.foo} == 'toto'")
.log("sending to beanA")
.to("bean:beanA")
.otherwise()
.log("sending to beanB")
.to("bean:beanB")
// close the choice() block :
.end()
// per the javadoc for marshall(), "the output will be added to the out body" :
.marshal().json(JsonLibrary.Jackson);
}
}
public class Foo {
private String foo; // Constructor and accessor omitted for brevity
}
public class Bar1 {
private String bar1; // Constructor and accessor omitted for brevity
}
public class Bar2 {
private String bar2; // Constructor and accessor omitted for brevity
}
public class BeanA {
public Bar1 doSomething(final Foo arg) {
return new Bar1(arg.getFoo() + "A");
}
}
public class BeanB {
public Bar2 doSomething(final Foo arg) {
return new Bar2(arg.getFoo() + "B");
}
}
POSTing {"foo":"toto"} returns {"bar1":"totoA"} (and logs sending to beanA).
POSTing {"foo":"titi"} returns {"bar2":"titiB"} (and logs sending to beanB).
It is as simple as this .marshal().json(JsonLibrary.Jackson) (this is what you want)

Spring Controller Advice to Trim JSON Data

I found an answer similar to this question but it isn't working when posting JSON data. I have the following:
#ControllerAdvice
public class ControllerConfig {
#InitBinder
public void initBinder ( WebDataBinder binder ) {
StringTrimmerEditor stringtrimmer = new StringTrimmerEditor(true);
binder.registerCustomEditor(String.class, stringtrimmer);
}
}
I know that the code is being reached during binding via debugging but when I pass in data like:
{ "companyId": " ABC "}
ABC isn't actually being trimmed during binding. My guess is that this only works with request params and not raw JSON bodies but not sure about that. If that is the case, is there something I can do that is similar?
Create this JsonDeserializer
public class WhiteSpaceRemovalDeserializer extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser jp, DeserializationContext ctxt) {
// This is where you can deserialize your value the way you want.
// Don't know if the following expression is correct, this is just an idea.
return jp.getCurrentToken().asText().trim();
}
}
and set this to your property
#JsonDeserialize(using=WhiteSpaceRemovalSerializer.class)
public void setAString(String aString) {
// body
}
Try this,
Create a class.
Annotate the class with #JsonComponent
extend the JsonDeserializer
and, add your trimming logic in the overridden method,
this will automatically trim the whitespaces in the json request, when it hits the controller, no external properties needed to activate this.
#JsonComponent
public class WhiteSpaceRemover extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser arg0, DeserializationContext arg1)
throws IOException, JsonProcessingException {
return arg0.getValueAsString().trim();
}
}

Castle MonoRail with asynchronous action view render exception

I'm trying to use async actions in MonoRail but when the view is rendered I get an NullReference exception, also tested with emtpy view file.
I also tried to call RenderView("uploadTags.vm") in EndUploadTags.
When I call RenderText(s) in EndUploadTags I don't get the exception.
Stacktrace:
[NullReferenceException: Object reference not set to an instance of an object.]
Castle.MonoRail.Framework.Services.DefaultCacheProvider.Get(String key) +163
Castle.MonoRail.Framework.Views.NVelocity.CustomResourceManager.GetResource(String resourceName, ResourceType resourceType, String encoding) +68
NVelocity.Runtime.RuntimeInstance.GetTemplate(String name, String encoding) +57
NVelocity.Runtime.RuntimeInstance.GetTemplate(String name) +82
NVelocity.App.VelocityEngine.GetTemplate(String name) +47
Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine.Process(String viewName, TextWriter output, IEngineContext context, IController controller, IControllerContext controllerContext) +564
Castle.MonoRail.Framework.Services.DefaultViewEngineManager.Process(String templateName, TextWriter output, IEngineContext context, IController controller, IControllerContext controllerContext) +237
Castle.MonoRail.Framework.Controller.ProcessView() +146
Castle.MonoRail.Framework.Controller.EndProcess() +1579
Castle.MonoRail.Framework.BaseAsyncHttpHandler.EndProcessRequest(IAsyncResult result) +141
[MonoRailException: Error processing MonoRail request. Action uploadtags on asyncController vendor]
Castle.MonoRail.Framework.BaseAsyncHttpHandler.EndProcessRequest(IAsyncResult result) +461
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +86
This is my test code:
private Output output;
public delegate string Output();
private string DoNothing()
{
return "nothing";
}
private string Upload()
{
return "upload";
}
public IAsyncResult BeginUploadTags(HttpPostedFile xmlFile, Boolean doUpload)
{
if (IsPost)
{
output = Upload;
return output.BeginInvoke(ControllerContext.Async.Callback, null);
}
output = DoNothing;
return output.BeginInvoke(ControllerContext.Async.Callback, null);
}
public void EndUploadTags()
{
var s = output.EndInvoke(ControllerContext.Async.Result);
PropertyBag["logging"] = s;
}
This is a bug in old versions of MonoRail. It works in MonoRail 2.1 RC, but not in an old version I just tried, I got the same null ref exception.
This is what revision 5688 looked like in Subversion, which is where the NullReferenceException is coming from. The code no longer uses the HttpContext for the cache.
public object Get(String key)
{
if (logger.IsDebugEnabled)
{
logger.DebugFormat("Getting entry with key {0}", key);
}
return GetCurrentContext().Cache.Get(key);
}
private static HttpContext GetCurrentContext()
{
return HttpContext.Current;
}

Getting and using remote JSON data

I'm working on a little app and using GWT to build it.
I just tried making a request to a remote server which will return a response as JSON.
I've tried using the overlay types concept but I couldn't get it working. I've been changing the code around so its a bit off from where the Google GWT tutorials left.
JavaScriptObject json;
public JavaScriptObject executeQuery(String query) {
String url = "http://api.domain.com?client_id=xxxx&query=";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
URL.encode(url + query));
try {
#SuppressWarnings("unused")
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// violation, etc.)
}
public void onResponseReceived(Request request,
Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
json =parseJson(response.getText());
} else {
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
return json;
}
public static native JavaScriptObject parseJson(String jsonStr) /*-{
return eval(jsonStr );
;
}-*/;
In the chrome's debugger I get umbrellaexception, unable to see the stack trace and GWT debugger dies with NoSuchMethodError... Any ideas, pointers?
You may have a look to GWT AutoBean framework.
AutoBean allow you to serialize and deserialize JSON string from and to Plain Old Java Object.
For me this framework became essential :
Code is cleaner than with JSNI objects (JavaScript Native Interface)
No dependancy with Framework not supported by Google (like RestyGWT)
You just define interfaces with getters and setters :
// Declare any bean-like interface with matching getters and setters,
// no base type is necessary
interface Person {
Address getAddress();
String getName();
void setName(String name):
void setAddress(Address a);
}
interface Address {
String getZipcode();
void setZipcode(String zipCode);
}
Later you can serialize or deserialize JSON String using a factory (See documentation) :
// (...)
String serializeToJson(Person person) {
// Retrieve the AutoBean controller
AutoBean<Person> bean = AutoBeanUtils.getAutoBean(person);
return AutoBeanCodex.encode(bean).getPayload();
}
Person deserializeFromJson(String json) {
AutoBean<Person> bean = AutoBeanCodex.decode(myFactory, Person.class, json);
return bean.as();
}
// (...)
First post on Stack Overflow (!) : I hope this help :)
Use JsonUtils#safeEval() to evaluate the JSON string instead of calling eval() directly.
More importantly, don't try to pass the result of an asynchronous call (like RequestBuilder#sendRequest() back to a caller using return - use a callback:
public void executeQuery(String query,
final AsyncCallback<JavaScriptObject> callback)
{
...
try {
builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable caught) {
callback.onFailure(caught);
}
public void onResponseReceived(Request request, Response response) {
if (Response.SC_OK == response.getStatusCode()) {
try {
callback.onSuccess(JsonUtils.safeEval(response.getText()));
} catch (IllegalArgumentException iax) {
callback.onFailure(iax);
}
} else {
// Better to use a typed exception here to indicate the specific
// cause of the failure.
callback.onFailure(new Exception("Bad return code."));
}
}
});
} catch (RequestException e) {
callback.onFailure(e);
}
}
Generally, the workflow you're describing consists of four steps:
Make the request
Receive the JSON text
Parse the JSON in JavaScript objects
Describe these JavaScript objects using an overlay type
It sounds like you've already got steps 1 and 2 working properly.
Parse the JSON
JSONParser.parseStrict will do nicely. You'll be returned a JSONValue object.
This will allow you to avoid using your custom native method and will also make sure that it prevents arbitrary code execution while parsing the JSON. If your JSON payload is trusted and you want raw speed, use JSONParser.parseLenient. In either case, you need not write your own parser method.
Let's say that you're expecting the following JSON:
{
"name": "Bob Jones",
"occupations": [
"Igloo renovations contractor",
"Cesium clock cleaner"
]
}
Since you know that the JSON describes an object, you can tell the JSONValue that you're expecting to get a JavaScriptObject.
String jsonText = makeRequestAndGetJsonText(); // assume you've already made request
JSONValue jsonValue = JSONParser.parseStrict(jsonText);
JSONObject jsonObject = jsonValue.isObject(); // assert that this is an object
if (jsonObject == null) {
// uh oh, it wasn't an object after
// do error handling here
throw new RuntimeException("JSON payload did not describe an object");
}
Describe as an overlay type
Now that you know that your JSON describes an object, you can get that object and describe it in terms of a JavaScript class. Say you have this overlay type:
class Person {
String getName() /*-{
return this.name;
}-*/;
JsArray getOccupations() /*-{
return this.occupations;
}-*/;
}
You can make your new JavaScript object conform to this Java class by doing a cast:
Person person = jsonObject.getJavaScriptObject().cast();
String name = person.getName(); // name is "Bob Jones"
Using eval is generally dangerous, and can result in all kinds of strange behavior, if the server returns invalid JSON (note, that it's necessary, that the JSON top element is an array, if you simply use eval(jsonStr)!). So I'd make the server return a very simple result like
[ "hello" ]
and see, if the error still occurs, or if you can get a better stack trace.
Note: I assume, that the server is reachable under the same URL + port + protocol as your GWT host page (otherwise, RequestBuilder wouldn't work anyway due to Same Origin Policy.)
You actually don't need to parse the JSON, you can use native JSNI objects (JavaScript Native Interface).
Here's an example I pulled from a recent project doing basically the same thing you're doing:
public class Person extends JavaScriptObject{
// Overlay types always have protected, zero argument constructors.
protected Person(){}
// JSNI methods to get stock data
public final native String getName() /*-{ return this.name; }-*/;
public final native String getOccupation() /*-{ return this.occupation; }-*/;
// Non-JSNI methods below
}
and then to retrieve it like so:
/**
* Convert the string of JSON into JavaScript object.
*
*/
private final native JsArray<Person> asArrayOfPollData(String json) /*-{
return eval(json);
}-*/;
private void retrievePeopleList(){
errorMsgLabel.setVisible(false);
String url = JSON_URL;
url = URL.encode(url);
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
try{
#SuppressWarnings("unused")
Request request = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request req, Response resp) {
if(resp.getStatusCode() == 200){
JsArray<Person> jsonPeople = asArrayOfPeopleData(resp.getText());
populatePeopleTable(people);
}
else{
displayError("Couldn't retrieve JSON (" + resp.getStatusText() + ")");
}
}
#Override
public void onError(Request req, Throwable arg1) {
System.out.println("couldn't retrieve JSON");
displayError("Couldn't retrieve JSON");
}
});
} catch(RequestException e) {
System.out.println("couldn't retrieve JSON");
displayError("Couldn't retrieve JSON");
}
}
So essentially you're casting the response as an array of JSON Objects. Good stuff.
More info here: http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html