I need to build a GWT application that will be called by an external application with specific URL parameters.
For example:
http://www.somehost.com/com.app.client.Order.html?orderId=99999.
How do I capture the orderId parameter inside the GWT application?
Try,
String value = com.google.gwt.user.client.Window.Location.getParameter("orderId");
// parse the value to int
P.S. GWT can invoke native javascript which means if javascript can do the stuff, GWT can do it too; e.g. in GWT, you can write
public static native void alert(String msg)
/*-{
$wnd.alert("Hey I am javascript");
}-*/;
In this case, you can even use existing javascript lib to extract param's value in the querystring.
GWT has a facility to get params from the URL:
String value = Window.Location.getParameter("param");
Make sure your URLs are in the form of:
http://app.com/?param=value#place instead of http://app.com/#place¶m=value
In order to get all params in a map, use:
Map<String, List<String>> map = Window.Location.getParameterMap();
I suggest you to use GWT MVP .
Assume that your url as
http://www.myPageName/myproject.html?#orderId:99999
And in your AppController.java --
Try as
......
public final void onValueChange(final ValueChangeEvent<String> event) {
String token = event.getValue();
if (token != null) {
String[] tokens = History.getToken().split(":");
final String token1 = tokens[0];
final String token2 = tokens.length > 1 ? tokens[1] : "";
if (token1.equals("orderId") && tonken2.length > 0) {
Long orderId = Long.parseLong(token2);
// another your operation
}
}
}
...........
Another option , you can also use with Spring MVC. Here is an example ...
// Below is in your view.java or presenter.java
Window.open(GWT.getHostPageBaseURL() + "customer/order/balance.html?&orderId=99999",
"_self", "enable");
// Below code in in your serverside controller.java
#Controller
#RequestMapping("/customer")
public class ServletController {
#RequestMapping(value = "/order/balance.html", method = RequestMethod.GET)
public void downloadAuctionWonExcel(#RequestParam(value = "orderId", required = true) final String orderId,
final HttpServletResponse res) throws Exception {
try {
System.out.println("Order Id is "+orderId);
// more of your service codes
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
You can use the Activities and Places to do that. When you create the Place for your page, you can set the orderId as a member. This member can be used afterwords when you create the Activity associated with the place (in ActivityMapper).
The only restriction is that you can't send the orderId as a normal parameter. You will have to use an url with this form :
127.0.0.1:60206/XUI.html?#TestPlace:orderId=1
Related
The class
public class Details {
private String name;
private String id;
//more attributes
}
I have a method which takes the http request and write an xml file based on the attribute the request wants (basically exporting specific fields that user wants).
Http Request body,
{
"isNameRequired": true,
"isIdRequired": true,
"isAttrRequired": false
// and other params to for filtering
}
Eg -> if the request wants only 'name' and 'id' values, the request will have booleans such as isNameRequired and IsIdRequired.
Based on this booleans my condition would look like
if (isNameRequired) {
// write name on file
}
if (isIdRequired) {
// write id on file
}
This is just an example. The actual attributes I want to write is more than 50 and I'm having that many booleans and multiple if checks to write.
Note : The entire process can happen n number of times.
There is list of Details (size > 100) which I need to loop through and write a xml based on users request.
If the user only needs name and id field, my xml should look like
<info>
<detail1>
<name>somename</name>
<id>someid</id>
</detail1>
<detail2>
<name>somename</name>
<id>someid</id>
</detail2>
</info>
like wise, if the request needs only name,
<info>
<detail1>
<name>somename</name>
</detail1>
<detail2>
<name>somename</name>
</detail2>
</info>
My question is, is this approach correct or is there a better way to handle this situation?
Well, it depends on your code but you could have some form of request handler that operates on a single requested element (e.g. "name"). If that fits your needs you could maintain a map of those handlers, get the ones you need and use them.
I'll add a simple example and assume your requests contain a number of strings for what's needed (if it's different I'll leave the conversion to you :) ):
interface RequestedElementHandler {
String getHandledElementName();
void handleElement(File xmlFile); //add anything else as needed
}
class NameHandler implements RequestedElementHandler {
public String getHandledElementName() { return "name"; }
public void handleElement(File xmlFile) {
//write name to file
}
}
And when handling your request:
Collection<String> requestedElements = ...;
//just an example, maintain a reusable map in a real world example
Map<String, RequestedElementHandler> handlers = new HashMap<>();
//you could use handlers.put("name", new NameHandler()) but doing it that way lets the handler define what elements it will work on
NameHandler nameHandler = new NameHandler();
handlers.put(nameHandler.getHandledElementName(), nameHandler());
//add other handlers as needed
for( String element : requestedElements ) {
RequestedElementHandler handler = handlers.get(element);
if( handler != null ) {
handler.handle(xmlFile);
}
}
Update:
Since your request body actually contains boolean properties you could modifiy the above approach as follows:
class NameHandler implements RequestedElementHandler {
//rename in interface
public String getPredicateName() { return "isNameRequired"; }
}
And when processing the request:
//extract the parameters from the request - how depends on whether you have
// - a ServletRequest: getParameterMap()
// - a Json object: try Jackon's ObjectMapper.readTree() and extract property names and values from the generic json object you get
// - anything else: can't tell without knowing but you should be able to do some research
Map<String, Boolean> parameters = ...
for( Map.Entry<String, Boolean> parameterEntry : parameters.entrySet() ) {
//reject FALSE and null
if( !Boolean.TRUE.equals(parameterEntry.getValue()) {
continue;
}
RequestedElementHandler handler = handlers.get(parameterEntry.getKey());
//use handler
}
Alternative:
Maintain a list of RequestHandler elements which all get the request and act on it if needed.
Example:
interface RequestHandler {
void handleRequest(Request r, File xmlFile);
}
class NameHandler implements RequestHandler {
void handleRequest(Request r, File xmlFile) {
if( !r.isNameRequired() ) {
return; //request doesn't require the name so skip
}
//add name to xml file
}
}
Usage:
Request request = ... //your request object
File xmlFile = ... //the file you want to write to
List<RequestHandler> handlers = ... //get from somewhere
handlers.forEach(handler -> handler.handleRequest(request, xmlFile));
I am working on a project where hkstd id generates and this id used by further HTTP Request Sampler. This hkstd id is generated by java code which developer has provided. My scenario is that I have to call first this java code which will return the id and then i will use this in my HTTP request. I have tried to call this Java code in Beanshell Sampler and in JSR223 Sampler but no result though this sampler passes the result without any error. When I try to put log/System.out then it prints nothing. I am not sure whether my code is running/calling or not ?
Thanks in advance!
Remove class and main method and just enter your code, e.g.:
import org.apache.commons.codec.digest.DigestUtils;
String contextRoot = "root";
String csrfToken = "a";
String url = "http://www.google.com/root?ta=b&_hkstd=1234c=d";
String urlWithQueryString = removeParamsAndHost(url, contextRoot);
String token = getHashValueOfUrl(urlWithQueryString, csrfToken);
String urlWithToken = findurlWithToken(url, token);
private static String findurlWithToken(String url, String token) {
StringBuilder builder = new StringBuilder(removeParams(url));
if (builder.indexOf("?") == -1) {
builder.append("?");
} else {
builder.append("&");
}
builder.append("_hkstd").append("=").append(token);
;
return builder.toString();
}
private static String removeParamsAndHost(String url, String contextRoot) {
if (url.indexOf("_hkstd") != -1) {
return url.substring(url.indexOf(contextRoot), url.indexOf("_hkstd") - 1);
} else {
return url.substring(url.indexOf(contextRoot));
}
}
private static String removeParams(String url) {
if (url.indexOf("_hkstd") != -1) {
return url.substring(0, url.indexOf("_hkstd") - 1);
} else {
return url;
}
}
public static String getHashValueOfUrl(String url, String csrfToken) {
return DigestUtils.md5Hex(url + csrfToken);
}
You can add a JMeter variable you can use later using vars.put:
vars.put("url", urlWithToken );
If you want to run this Java class as it is:
Compile the source code provided by the developer and put the resulting .jar file under JMeter Classpath
Restart JMeter to pick the .jar up
Add JSR223 Sampler to your Test Plan
Put the following code into "Script" area:
AppendHtstd.main()
That's it, your class will be executed by JMeter
See Apache Groovy - Why and How You Should Use It article to learn more about custom scripting in JMeter tests
I'm doing an API in my web system because of a task in university. The problem is that I'm not able to do a specific part and I think that it's very easy.
The statement says:
*GET /rest/api/v1/tfg?State = ${state}
List of all TFGs in the indicated state. You can indicate different states at the same time. To do this, you must repeat the state parameter multiple times (such as: "?State=state1&State=state2&State=state3"), and the web service will return all those who are in any of these states.*
I have a DB with projects (TFGs) and I know how to get this data, but the problems are that I don't know what to do to detect ? in URL, and how can I do to read different parameters depending on the quantity. It's possible to have one state or N states. How can I do it?
The current code is this:
#Path("/rest/api/v1/tfg")
public class TfgREST {
#GET
#Path("")
#Produces(MediaType.APPLICATION_JSON)
public Response findAll() throws ServletException, IOException {
TfgDao dao = new TfgDao();
LinkedList<Projecte> llista = dao.findAll(true); //TRUE because of API
JsonArrayBuilder array = Json.createArrayBuilder();
for(Projecte p : llista){
array.add(p.getTitol());
}
return Response.ok(array.build()).build();
}
#GET
#Path("/?state={state}")
#Produces(MediaType.APPLICATION_JSON)
public Response findByState(#PathParam("state") String state) throws ServletException, IOException {
TfgDao dao = new TfgDao();
LinkedList<String> llista = dao.findByState(state);
//JsonObjectBuilder jo = Json.createObjectBuilder();
JsonArrayBuilder array = Json.createArrayBuilder();
for(String p : llista){
array.add(p);
}
return Response.ok(array.build()).build();
}
If I call http://...../rest/api/v1/tfg?State=XXXX, web invokes the first one (findAll) but, if I use /rest/api/v1/tfg/State=XXX it works...
Thanks for all! I'm waiting for your answers.
Miquel
Because REST API follows resource.
if "state" is a object, you can use /rest/api/v1/tfg/State=XXX
BUT if "state" is only a property of tfg, you use /rest/api/v1/tfg?State=XXX
Ok guys, now it's working. I publish the solution in order to contribute with you and try to solve this problem in a future for other people.
I mixed both methods in one implemeting an if.
The code is the following:
#Path("/rest/api/v1/tfg")
public class TfgREST {
#GET
#Path("")
#Produces(MediaType.APPLICATION_JSON)
public Response findAll(#QueryParam("state") List<String> state) throws ServletException, IOException {
TfgDao dao = new TfgDao();
JsonArrayBuilder array = Json.createArrayBuilder();
if(state.isEmpty()){
LinkedList<Projecte> llista = dao.findAll(true); //TRUE because of API
for(Projecte p : llista){
array.add(p.getTitol());
}
}
else{
LinkedList<String> projs;
for (String s : state){
projs = dao.findByState(s);
for (String x : projs){
array.add(x);
}
}
}
return Response.ok(array.build()).build();
}
}
Thanks for your contributions, I finally got it, and it has been very easy!
On Server side, there is a JNDI resource, that I need to read from a Client GWT App.
I know, that I can make a GWT RPC call to get the JNDI resource dynamically, but the JNDI resource is a static URL, that will not change, once the page is loaded. So - my idea was to load the JNDI resource when loading the page.
I found an outdated description about how this could be done - in 2011
https://webtide.com/gwt-and-jndi/
However, I would like to know, whether this would be possible for a more current version of GWT (I am using GWT 2.7.0)
I had the same problem. Pass JNDI parameters and some other configuration values to the GWT application.
The trick is to generate the GWT hostpage dynamically (with JSP in my case).
Each inital call to my GWT application goes to a front controller (a Servlet) for authorizition purposes and some other intitialization stuff.
Then I get all the JNDI parameters and other values, put them into the request context and call the hostpage JSP.
In my JSP page I define a JavaScript hash and initialize it with the parameters.
<script type="text/javascript">
var my_params = {
jndiParam1: '<%= request.getAttribute("jndiParam1") %>',
exampleUrl: '<%= request.getAttribute("exampleUrl") %>',
jndiParam2: '<%= request.getAttribute("jndiParam2") %>'
};
</script>
And inside my GWT application I have a class HostPageParameter which uses a com.google.gwt.i18n.client.Dictionary to access the JavaScript hash my_params.
public class HostPageParameter {
private static final String DICTNAME = "my_params";
private static HostPageParameter instance = null;
public static HostPageParameter getInstance() {
if(instance == null) {
instance = new HostPageParameter();
}
return instance;
}
private Dictionary myParams;
private HostPageParameter() {
try {
myParams = Dictionary.getDictionary(DICTNAME);
} catch(MissingResourceException e) {
// If not defined
myParams = null;
}
}
public String getParameter(String paramName) {
return getParameter(paramName, null);
}
public String getParameter(String paramName, String defaultValue) {
String paramValue = null;
if(myParams != null && paramName != null) {
try {
paramValue = myParams.get(paramName);
} catch (MissingResourceException e) {
// If not defined
paramValue = defaultValue;
}
}
return paramValue;
}
}
And to read the values you simply can use:
// Without a default value, If not defined, null is returned.
final String jndiParam1 = HostPageParameter.getInstance().getParameter("jndiParam1");
// With default value.
final String exampleUrl = HostPageParameter.getInstance().getParameter("exampleUrl",
"http://example.com");
Where can I find Jira issue type values that we pass to IssueBuilder class constructor?
For ex: If i want to create a issue type of bug using jira rest api , We pass value '1L' to Issue Builder class constructor.
IssueInputBuilder issueBuilder = new IssueInputBuilder("Key", 1l);
Similarly what are the values of other jira issue types ?.. Anybody know the values we need to pass ?
If you are using later Jira REST Java Client API (e.g. 4.0), the interface has been changed. You must use following code to browsing all issue types:
private static final String JIRA_SERVER = "http://jiralab";
public static void main(String[] args) {
try {
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
URI uri = new URI(JIRA_SERVER);
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, "admin", "admin");
listAllIssueTypes(client);
}
catch (Exception ex) {
}
}
private static void listAllIssueTypes(JiraRestClient client) throws Exception {
Promise<Iterable<IssueType>> promise = client.getMetadataClient().getIssueTypes();
Iterable<IssueType> issueTypes = promise.claim();
for (IssueType it : issueTypes) {
System.out.println("Type ID = " + it.getId() + ", Name = " + it.getName());
}
}
If you want to get a list of all available issuetypes, you can use the REST API (/rest/api/2/issuetype). To try that on your JIRA instance, I like to recommend the Atlassian REST API Browser.
Or just look here: Finding the Id for Issue Types
In Java you can get a list of all issuetype object using getAllIssueTypeObjects().