Post Request to Wicket - wicket

With Wicket,
How can I send the var slideCounter to Wicket?
Can someone provide an example?
I am unable find more information on this.
$(document).on('click', '.lean-overlay', function() {
var slideCounter = 0;
// TODO Send slidecounter to wicket
});

Sending the request is as simple as: Wicket.Ajax.post({"u": "the/url?slideCounter="+slideCounter})
The more complex part is to construct the/url.
To send it to a Component this Component should implement IRequestListener interface. To construct the url use: requestCycle.urlFor(component)
To send it to a Behavior better instantiate AbstractDefaultAjaxBehavior and use its #getCallbackUrl()
Once you have the url you need to store it in the page DOM, e.g. with OnDomReadyHeaderItem.forScript("window.TheUrl='"+theUrl+"';")

You have the possibility to call wicket code from javascript using ajax call backs. You can do something like this:
JAVA CODE:
AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
#Override
public void renderHead(Component component, IHeaderResponse response) {
super.renderHead(component, response);
String componentMarkupId = component.getMarkupId();
String callbackUrl = getCallbackUrl().toString();
response.render(JavaScriptHeaderItem.forScript(
"var componentMarkupId='" + componentMarkupId
+ "'; var callbackUrl='" + callbackUrl + "';",
"values"));
}
protected void respond(final AjaxRequestTarget target) {
IRequestParameters parameters = RequestCycle.get().getRequest()
.getQueryParameters();
// write yout java code here
// if you want to use the slideCounter variable
// you have to retrieve its value like this:
// parameters.getParameterValue("slideCounter").toString()
}
};
add(behave);
JAVASCRIPT CODE:
$(document).on('click', '.lean-overlay', function() {
var slideCounter = 0;
executeJava(slideCounter);
});
function executeJava(slideCounter) {
try {
var commandToSend = 'slideCounter=' + slideCounter;
var wcall = Wicket.Ajax.post({
u: callbackUrl + '&' + commandToSend
});
} catch (e) {
alert(e);
}
}

Related

Facebook login manual flow with error

After I dealt with this error a verified many fori and all mentioned that the solution for this error would be having in Facebook settings the “Valid OAuth Redirect URIs” set to “https://www.facebook.com/connect/login_success.htm”, what it is, so that is not the issue. Furthermore, all solutions found are too old and use obsolete components.
Said that using Xamarin Forms I’m trying to do the manual flow to login into Facebook as described in “https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow”.
The code is:
using Authentication.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Authentication
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FacebookProfilePage : ContentPage
{
private string ClientId = "910688099117930";
public FacebookProfilePage()
{
InitializeComponent();
var apiRequest =
"https://www.facebook.com/dialog/oauth?client_id="
+ ClientId
+ "&display=popup&response_type=token&redirect_uri=http://www.facebook.com/connect/login_success.html"
+ "&state=state123abc";
var webView = new WebView
{
Source = apiRequest,
HeightRequest = 1
};
webView.Navigated += WebViewOnNavigated;
Content = webView;
}
private async void WebViewOnNavigated(object sender, WebNavigatedEventArgs e)
{
var accessToken = ExtractAccessTokenFromUrl(e.Url);
if (accessToken != "")
{
var vm = BindingContext as FacebookViewModel;
await vm.SetFacebookUserProfileAsync(accessToken);
Content = MainStackLayout;
}
}
private string ExtractAccessTokenFromUrl(string url)
{
if (url.Contains("access_token") && url.Contains("&expires_in="))
{
var at = url.Replace("https://www.facebook.com/connect/login_success.html#access_token=", "");
if (Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows)
{
at = url.Replace("http://www.facebook.com/connect/login_success.html#access_token=", "");
}
var accessToken = at.Remove(at.IndexOf("&expires_in="));
return accessToken;
}
return string.Empty;
}
}
}
Please, notice that this is a open code, found in “https://github.com/HoussemDellai/Facebook-Login-Xamarin-Forms”, which historically has proven itself to work fine.
The URL that I send to login is: “https://www.facebook.com/v3.0/dialog/oauth?client_id=910688099117930&response_type=token&redirect_uri=http://www.facebook.com/connect/login_success.html”. I always get the error message: “Not Logged In: You are not logged in. Please login and try again.”.
Can anyone tell me what’s wrong here?
And before any comment, yes, I’ll delete this App Id as soon as the problem is solved and change it for a new one 😊

AEM 6.1 Sightly basic form submit and redirect to same page

I am trying to do the following on AEM 6.1:
Develop a simple form (3 input fields)
Process the submitted values,
And redirect to the same page with processed values/result
I am able to submit the values to a servlet, and process them (business logic), and the result to a requestparamter so i can retrieve them on the UI. But i am stuck at these:
Redirecting to the same page
And retrieving the request parameters and display them using Sightly.
Code Snippets:
Servlet
#SlingServlet(
methods = { "POST","GET" },
name="com.tti.tticommons.service.servlets.LeadTimeTrendsServlet",
paths = { "/services/processFormData" }
)
public class TTICommonServlet extends SlingAllMethodsServlet{
...
#Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {
String result;
try {
Enumeration<String> parameterNames = request.getParameterNames();
Map<String, String> formParametersMap = new HashMap<String, String>();
while (parameterNames.hasMoreElements()) {
paramName = parameterNames.nextElement();
paramValue = request.getParameter(paramName);
.......
.......
}
request.setAttribute("result",result);
response.sendRedirect("/content/ttii/en/**posttest.html**");
}
}
Can anyone please help on ho to retireve the above "result" in posttest.html using sightly.
After lot of research and several trials, i finally had the code working. I had to pick up related info from several answers in stackoverflow. Thanks to all the authors. Posting my solution here so beneficial for others.
Result Form with response from webservice:
Process flow
Submit form data to Servlet's POST method
In Servlet, get the values entered by the user from the request
Make the necessary webservice calls. Get the response(json)
I added the response-json as a parameter to the request
Using Wrapper, forward to the necessary page
Define a WCMUse class for use with Sightly.
Assign the 'request' to the Use-class and process it there
Use the assigned values from the Use-class to the UI using sightly
Code snippets - HTML
<form name="userRegistrationForm" method="post" action="/services/processFormData">
<input type="hidden" name=":redirect" value="posttest.html" />
<input type="submit" title="Submit" class="btn submit btn-success" value="Submit" tabindex="25" name="bttnAction">
<div data-sly-use.model="${'com.abccommons.service.helpers.PostServiceHelper' # slingreq=request }">
**${model.getRawJson}**
</div>
Code snippets - Servlet
#SlingServlet(
label = "ABC - Common Servlet",
metatype = true,
methods = { "POST" },
name="com.abccommons.service.servlets.ABCPostServlet",
paths = { "/services/processFormData" }
)
public class ABCPostServlet extends SlingAllMethodsServlet{
#Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {
log.info("\n\n----- ABCPostServlet POST: ");
String paramName;
String paramValue;
String osgiService="";
try {
Enumeration<String> parameterNames = request.getParameterNames();
Map<String, String> formParametersMap = new HashMap<String, String>();
while (parameterNames.hasMoreElements()) {
paramName = parameterNames.nextElement();
paramValue = request.getParameter(paramName);
if (paramName.equals("osgiService")) {
osgiService = paramValue;
} else if (paramName.equals(":cq_csrf_token")) {
//TODO: don't add to the map
} else if (paramName.equals("bttnAction")) {
//TODO: dont' add to the map
} else {
//log.info("\n---ParamName="+paramName+", value="+paramValue);
formParametersMap.put(paramName, paramValue);
}
}
String parametersInJSON = JSONHelper.toJson(formParametersMap);
log.info("\n\n----------- POST paramters in json="+parametersInJSON);
String json = webServiceHelper.getJSON(osgiService, parametersInJSON, request, response);
log.info("\n\n----------- POST json from web service="+json);
request.setAttribute("jsonResponse",json);
//String redirectPage = request.getParameter(":redirect");
//RequestDispatcher dispatcher = request.getRequestDispatcher("/content/en/"+redirectPage);
RequestDispatcher dispatcher = request.getRequestDispatcher("/content/en/postformtest.html");
GetRequest getRequest = new GetRequest(request);
dispatcher.forward(getRequest, response);
} catch (Exception e) {
log.error("SlingServlet Failed while retrieving resources");
} finally {
//TODO
}
}
/** Wrapper class to always return GET for AEM to process the request/response as GET.
*/
private static class GetRequest extends SlingHttpServletRequestWrapper {
public GetRequest(SlingHttpServletRequest wrappedRequest) {
super(wrappedRequest);
}
#Override
public String getMethod() {
return "GET";
}
}
Code snippets - PostServiceHelper - WCMUSe class
public class PostServiceHelper extends WCMUse {
protected final Logger log = LoggerFactory.getLogger(PostServiceHelper.class);
private SlingHttpServletRequest httpRequest;
private String rawJson;
#Override
public void activate() throws Exception {
log.info("\n\n========= PostServiceHelper.activate():"+get("slingreq", SlingHttpServletRequest.class));
this.httpRequest = get("slingreq", SlingHttpServletRequest.class);
//this.resourceResolver = getResourceResolver();
//log.info("\n\n========= getRequest()="+getRequest());
SlingHttpServletRequest tRequest;
Set<String> keys = new HashSet<String>();
Enumeration<?> attrNames = this.httpRequest.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attr = (String) attrNames.nextElement();
//log.info("\n--- Key="+attr);
if (attr.equals("jsonResponse")) {
this.setRawJson((String)this.httpRequest.getAttribute(attr));
//log.info("\n---rawJson is SET with : "+this.rawJson);
}
}
}
public void setRawJson(String json) {
this.rawJson = json;
}
public String getRawJson() {
return this.rawJson;
}
}
This is actually a rather tricky pattern to achieve in Sling. You may be better served by submitting the form asynchronously and updating your HTML dynamically via JavaScript.
If you do need to submit your form in the manner you specify, then your servlet needs to produce the HTML response. To produce a response made up of a rendering of the page identified by the requested path your servlet will need to dispatch the request to the appropriate rendering mechanism. You can reference Get JSP output within Servlet in AEM for information concerning how that can be accomplished. Upon dispatch your page and its components should have access to the submitted form values as well as the attributes set on the request.

How does REST authentication work for client-side apps?

I'm trying to design my first public API, and I'm trying to learn how REST works with authentication, especially in the context of completely client-side apps using js-frameworks, e.g., angularJS.
Say you have a client which is a browser application (i.e., HTML, JS, CSS only) served as static files from something like nginx using a javascript framework to consume a REST service from, e.g. something that requires a secret access key that's used to create a signature for each request to the service, something like Amazon S3.
In terms of authentication in this scenario, where you don't have a server-side application, how would the secret access key be handled, i.e., how do you get it, where do you store it, etc.? It would seem like a horrible security situation to serve the key for each request (even if it only happens once to bootstrap the application).
And even if you do have a light server-side application--how do you securely inform the client (which still calls the authenticated 3rd party API itself) what the signature should be for every request it could possibly make? I'm very confused by how this is supposed to be designed from either end.
I've done a few AngularJS apps and the way that I've found is to use an HttpModule like this one:
using System;
using System.Net.Http.Headers;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
namespace YourSolution.WebApp.Modules
{
public class BasicAuthenticationHttpModule : IHttpModule
{
public BasicAuthenticationHttpModule()
{
}
public void Init(HttpApplication context)
{
context.AuthenticateRequest += OnApplicationAuthenticateRequest;
context.EndRequest += OnApplicationEndRequest;
}
private static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private static bool CheckPassword(
string username, string password)
{
return username == password;
}
private static void AuthenticateUser(string credentials)
{
try
{
var encoding = Encoding.GetEncoding(
"iso-8859-1");
credentials = encoding.GetString(
Convert.FromBase64String(credentials));
var separator = credentials.IndexOf(':');
var name = credentials.Substring(0, separator);
var password = credentials.Substring(separator + 1);
var validated = CheckPassword(name, password);
if (!validated) return;
var identity = new GenericIdentity(name);
SetPrincipal(new GenericPrincipal(identity, null));
}
catch (FormatException)
{
}
}
private static void OnApplicationAuthenticateRequest(
object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
var authHeader = request.Headers["Authorization"];
if (authHeader == null) return;
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
if (authHeaderVal.Scheme.Equals(
"basic",
StringComparison.OrdinalIgnoreCase)
&& authHeaderVal.Parameter != null)
{
AuthenticateUser(authHeaderVal.Parameter);
}
}
private static void OnApplicationEndRequest(
object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
if (response.StatusCode == 401)
{
//response.Headers.Add(
// "WWW-Authenticate",
// string.Format("Basic realm=\"{0}\"", Realm));
}
}
public void Dispose()
{
}
}
}
The most important part is inside CheckPassword method, there is where you should validate the credentials.
Another point is this line response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", Realm)); if you don't comment this line, the classic login requested form will show up, and if you do comment this line you have to catch the 401 error in your requests.
If you want to know about realm: What is the “realm” in basic authentication.
Plus, you will need to register the module in your web.config file:
<system.webServer>
<modules>
<add
name="BasicAuthenticationHttpModule"
type="YourSolution.WebApp.Modules.BasicAuthenticationHttpModule" />
</modules>
</system.webServer>
Then I've added these two methods to deal with the authentication token:
// u: username; p: password
CreateBasicAuthenticationToken = function (u, p) {
var t = u + ':' + p;
var hat = btoa(t);
window.sessionStorage.setItem('basicauthtoken', 'basic ' + hat);
};
DestroyBasicAuthenticationToken = function () {
window.sessionStorage.removeItem('basicauthtoken');
};
The btoa method: The btoa() method of window object is used to convert a given string to a encoded data (using base-64 encoding) string.. Taken from: http://www.w3resource.com/javascript/client-object-property-method/window-btoa.php.
And last I've added the authtoken to the request header using the beforeSend:
$.ajax({
type: 'GET',
url: 'your url',
beforeSend: function (xhr) {
window.sessionStorage.getItem('basicauthtoken');
}
}).done(function (data, textStatus, xhr) {
//...
});
Please do note using jQuery outside an angular directive is not recommended, AngularJS best practices dictates jQuery code must be always placed inside a directive.
Hope it helps.

Passing the Ajax request data parameter through Zend Framework Controller to model class

I am Using the Zend Framework.
As a design pattern i am using the state design pattern.
Now as you may know, Zend Framework let's you create custom controllers, which can be used to respond to Ajax requests.
In my example i have the following ajax request
function getResponse(name){
$.ajax({
dataType: 'json',
data: {button: name},
url: 'motor/ajaxtest',
type: 'post',
success: function(response)
{
}
});
}
The function getResponse is called every time a specific button is pressed.
public function ajaxtestAction()
{
$input_in = $this->getRequest()->getParam('button');
$Lok = new Lok();
$this->_helper->viewRenderer->setNoRender();
$text = array($Lok->getMotorState());
$phpNative = Zend_Json::encode($text);
echo $phpNative;
}
The Code above is my custom response to the ajax request. I want to pass on the name of the pressed button to $Lok = new Lok(); so i can use it in the "Lok" model Class without creating a new instance of The controller in the "Lok" class
Is there anyone who might be able to help me ?
EDIT-----------------------------------
Here's my Controller :
class MotorController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
}
public function ajaxtestAction()
{
$input_in = array($this->getRequest()->getParam('button'));
$phpNativ1 = Zend_Json::encode($input_in);
echo $phpNativ1;
$Lok = new Lok();
echo $input_in;
$this->_helper->viewRenderer->setNoRender();
$text = array($Lok->getMotorState());
$phpNative = Zend_Json::encode($text);
echo $phpNative;
}
}
Here are my Jquery functions :
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
$("input[name=State]").val('Forwards');
});
function getResponse(name){
$.ajax({
dataType: 'json',
data: {button: name},
url: 'motor/ajaxtest',
type: 'post',
success: function(response)
{
}
});
}
$("button[name=on]").click(function() {
var d_response = getResponse('on');
});
});
And this is my Lok.php file :
class Lok
{
private $newMotor;
private $newTimer;
private $newSpeaker;
private $mySession;
private $motorState;
private $input;
public function __construct()
{
//Method instances
$newMotor = new Motor();
$newTimer = new Timer();
$newSpeaker = new Speaker();
$this->motorState = $newMotor->getMotorState();
// Declaring the Session
$mySession = new Zend_Session_Namespace();
$mySession->s_motorState = $this->motorState;
}
public function __get($mySession)
{
return $this->mySession;
}
public function __set($motorState, $mySession)
{
$this->$mySession->s_motorState = $motorState;
}
public function getMotorState()
{
return $this->motorState;
}
public function playSound($soundNumber)
{
echo "Playing sound";
}
public function resetTimer()
{
echo "Resetting timer";
}
public function setInput($input_in)
{
$this->input=$input_in;
}
}
As i've stated previously you should get the button name by calling the requests post data, this is done by $postData = $this->getRequest()->getPost()
Then, to get the output into your Model, inside your model class you would create a property as well as setter and getter method for it.
class Lok {
protected $button;
public function setButton($btn){}
public function getButton(){}
}
And then it becomes as easy as doing something like
$lokModel->setButton($postData['button'])
First of all, thanks for posting your solution.
I tried to implement your solution but unfortunaly it didnt work.
So after a good night sleep, i looked at the problem again. I think the problem is, that
$postData = $this->getRequest()->getPost() or $postData = $this->getRequest()->getParam('button')
is executed in the response itelfe.
<pre>string(2) "sr"
</pre>["Not Moving"]
This is what the JSON response looks like in The Google Chrom debugger. If you'r familliar with this Google Chrome debugger you know what i mean.
Now the button name that i want is in between the &quot tags the only problem is, getting it out of there. and being able to use it before the response is triggerd. I also tried getPost() and getParam('button') in the init() and indexAktion() Methods in the Controller but it still didn't work
public function init()
{
postData = $this->getRequest()->getPost()
$lokModel->setButton($postData['button'])
}
public function indexAction()
{
postData = $this->getRequest()->getPost()
$lokModel->setButton($postData['button'])
}
Any other ideas ?

How to translate,use JSON in GWT?

I'm new in gwt. and need to know how to use JSON in gwt so i try this simple data loader but i'm still confuse.
I create a project named 'tesdb3' in eclipse. I create the PHP side to access the database, and made the output as JSON.. I create the userdata.php in folder war. then I compile tesdb3 project. Folder tesdb3 and the userdata.php in war moved in local server(I use WAMP). I put the PHP in folder tesdb3. This is the result from my localhost/phpmyadmin/tesdb3/userdata.php
[{"kode":"002","nama":"bambang gentolet"}{"kode":"012","nama":"Algiz"}]
From that result I think the PHP side was working good.Then I create UserData.java as JSNI overlay like this:
package com.tesdb3.client;
import com.google.gwt.core.client.JavaScriptObject;
class UserData extends JavaScriptObject{
protected UserData() {}
public final native String getKode() /*-{ return this.kode; }-*/;
public final native String getNama() /*-{ return this.nama; }-*/;
public final String getFullData() {
return getKode() + ":" + getNama();
}
}
Then Finally in the tesdb3.java:
public class Tesdb3 implements EntryPoint {
String url= "http://localhost/phpmyadmin/tesdb3/datauser.php";
private native JsArray<UserData> getuserdata(String json)
/*-{
return eval(json);
}-*/;
public void LoadData() throws RequestException{
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
builder.sendRequest(null, new RequestCallback(){
#Override
public void onError(Request request, Throwable exception) {
Window.alert("error " + exception);
}
public void onResponseReceived(Request request,
Response response) {
//1
//data(getuserdata(response.getText()));
//2
JsArray<UserData> uda = JsonUtils.unsafeEval(response.getText())
data(uda);
}
});
}
public void data(JsArray<UserData> data){
for (int i = 0; i < data.length(); i++) {
String lkode =data.get(i).getKode();
String lname =data.get(i).getNama();
Label l = new Label(lkode+" "+lname);
tb.setWidget(i, 0, l);
}
RootPanel.get().add(new HTML("my data"));
RootPanel.get().add(tb);
}
public void onModuleLoad() {
try {
LoadData();
} catch (RequestException e) {
e.printStackTrace();
}
}
}
The result from both method i use in the onResponseReceived is the same. Just showing string "my data". but the method 2 create eror like this:
14:41:59.875 [ERROR] [tesdb3] Uncaught exception escaped
com.google.gwt.core.client.JavaScriptException: (SyntaxError): syntax error
Did I miss use the 2nd method? Why method 1 didn't have any eror but can't show the data?
The problem is that your JSON has incorrect syntax, you are missing a comma after the first item of the table, it should be (whitespace added for readability):
[
{
"kode": "002",
"nama": "bambang gentolet"
},
{
"kode": "012",
"nama": "Algiz"
}
]
Since JSON is a part of JavaScript this might be the syntax error exception you are getting.
PS: I'd recommend using some PHP framework to create JSON for you (Zend Framework is my usual choice). Also, JSON validators like JSONLint are very useful for debugging JSON.
It looks like a typo in your code, which brings me to naming conventions: for variables and methods use camel case, starting with a lower case character. Thus UserData UD should be UserData ud.
In your getuserdata method (which should be getUserData) you use the parameter name Json with capital J and in the native code json with the lower j. This explains the error.
Regarding the getUserData method. There is a GWT method: JsonUtils.unsafeEval(json) which you should use.
Furthermore, the code in the onResponseReceived seems incomplete, it might not be of importance as it might be incorrectly be put in this example, but just to be complete, here is what it should look like:
JsArray<UserData> uda = JsonUtils.unsafeEval(response.getText());
for (int i = 0; i < uda.length(); i++) {
UserData ud = uda.get(i);
String lKode = ud.getKode();
String lName = ud.getNama();
Label l = new Label(lKode + " " +lName);
RootPanel.get().add(l);
}