I am curious as to what a better way to deal with this is, I wanted to challenge my self and see if I could break up, in a HashMap of key,value (or String, String), a string that could come back in almost any format.
the string in question is:
/user/2/update?updates=success
Thats right, a url request for a server. The issue - as we all know this could be any thing, it could come back in any form. I wanted to break it up so that it would look like:
Controller => user
action => update
params => ??? (theres a 2, a update=success ... )
Obviously The above is not a real java object.
But you get the idea.
What do you need? what have you done? what are you trying to do?
What I want to do is map this to a controller and action while passing in the parameters along the way. But i need to separate this up making sure to specify each step what is what.
What I have done is:
private Filter parseRoute(String route){
String[] parsedRoute = route.split("[?:/=]");
Filter filter = new Filter(parsedRoute);
return filter;
}
Splits on any thing that is in the url (note, : would be something like /user:id/update
so: user/2/update ... )
I then attempted to do:
public class Filter {
private HashMap<String, String> filterInfo;
public Filter(String[] filteredRoute){
if(filteredRoute.length > 0){
filterInfo.put("Controller", filteredRoute[0]);
}else{
throw new RoutingException("routes must not be empty.");
}
}
}
But this is not going to work as I expected it to...As there are too many variables at play.
including parameters before the action (those would just be used to search for that user), their could be nested routes, so multiple controller/action/controller/action ..
How would you deal with this? What would you suggest? How could you get around this? Should you just do something like:
route(controller, action, params, template); ? (template lets you render a jsp). if so how do you deal with the ?update=success
I am using HttpServer to set up the basics. But I am now lost. I am trying to keep routing as generic and "do what ever you want we will map it to the right controller, action and pass in the parameters" but I think I bit off more then I can chew.
I have looked at both spark and spring framework, and decided that the route you pass, we will map to a xml file to find the controller and action, I just need the data structure in place to do that ...
So I am looking to back up and still go with "pass me something, ill map it out."
I would probably use the URL from apache,
org.apache.tomcat.util.net.URL url = null;
try {
url = new org.apache.tomcat.util.net.URL("/user/2/update?updates=success");
// ... do some stuff with it...
} catch (Exception e) {
e.printStackTrace();
}
java.net.URI may help you.
you can get your path by getPath()
and get all of your query by getQuery(),then you can split the query by = to name value pairs.
URI uri = new URI("/user/2/update?updates=success");
// /user/2/update
System.out.println("path is " + uri.getPath());
// updates=success
System.out.println("query is " + uri.getQuery());
Related
in my project i would want to implement a plugin for JMeter.
So currently I am stuck at sampler - postprocessing step.
#Override
public void postProcessSampler(HTTPSamplerBase sampler, SampleResult result)
{
super.postProcessSampler(sampler, result);
String postData = sampler.getPropertyAsString(HTTPSamplerBase.ARGUMENTS);
// ...
// apply some operations to postData
// ...
//
// try to write it back to sampler : approach1
// sampler.removeProperty(HTTPSamplerBase.ARGUMENTS);
// sampler.addNonEncodedArgument(HTTPSamplerBase.ARGUMENTS, postData, "");
// Fails
}
So at the postprocessing step i would like to change the request body, whcih is usually stored in HTTPSamplerBase.ARGUMENTS property. However, somehow i cannot set anything to this field. Redefining it with another string gives me a class cast error. If I try operating with strings, then i get invocation exception...
So my question is, what is the correct way to change the sampler's post body?
Regards and thank you
Try out HTTPSamplerBase.getArguments() function instead, example code:
sampler.getArguments().removeAllArguments();
sampler.addNonEncodedArgument("foo","bar","");
sampler.setPostBodyRaw(true);
Also be aware that for this form of post-processing you don't even need to come up with a plugin, all can be done via JSR223 PostProcessor and Groovy language. The above code should work just fine
I'm using Java 8. I want to extract the domain portion of a URL. Just in case I'm using the word "domain" incorrectly, what i want is if my server name is
test.javabits.com
I want to extract "javabits.com". Similarly, if my server name is
firstpart.secondpart.lastpart.org
I want to extract "lastpart.org". I tried the below
final String domain = request.getServerName().replaceAll(".*\\.(?=.*\\.)", "");
but its not extracting the domain properly. Then I tried what this guy has in his site -- https://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/, e.g.
private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$";
but that is also not extracting what I want. How can I extract the domain name portion properly?
Summary: Do not use regex for this. Use whois.
If I try to extrapolate from your question, to find out what you really want to do, I guess you want to find the domain belonging to some non-infrastructural owner from the host part of a URL. Additionally, from the tag of your question, you want to do it with the help of a regex.
The task you are undertaking is at best impractical, but probably impossible.
There are a number of corner cases that you would have to weed out. Apart from the list of infrastructural domains kindly provided by Lennart in https://publicsuffix.org/list/public_suffix_list.dat, you also have the cases of an empty host field in the URL or an IP-address forming the host part.
So, is there a better approach to this? Of course there is. What you do want to do is query a public database for the data you need. The protocol for such queries is called WHOIS.
Apache Commons provide an easy way to access WHOIS information in the WhoisClient. From there you can query the domain field, and find some more information that may be useful to you.
It shouldn't be harder than
import org.apache.commons.net.whois.WhoisClient;
import java.io.IOException;
public class CommonsTest {
public static void main(String args) {
WhoisClient c = new WhoisClient();
try {
c.connect(WhoisClient.DEFAULT_HOST);
System.out.println(c.query(URL));
c.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Using this will get you the whois information aboutt he domain you are asking for. If the domain is uregistered, that is, is a private domain, as in the case of www.stackexchange.com you will get an error saying no domain is registered. Remove the first part of the address and try again. Once you found the registered domain, you will also find the registrar and the registrer.
Now, unfortunately, whois is not as simple as one would think. Read further on https://manpages.debian.org/jessie/whois/whois.1.en.html for an elaboration on how to use it and what information you can expect from different sources.
Also, check related questions here.
try it like this:
String parts[] = longDomain.split(".");
String domain = parts[parts.length-2] + "." + [parts.length -1];
I'm trying to implement a basic web application from the values that we are getting from web-service, it will include two datatables, each of them need to be populated in server-side.
For example, web-service have a structure like this ( Let's say these are books)
Firstly i am getting the string GUID value for the objects that i want to get an information, after that i am sending a request with the parameter of this GUIDs to service to get information XML for these book objects that includes name, page and author of them.
But as an important information, my servlet needs to get these values dynamically as soon as the page of datatable is changed, if this datatable will include 30 book ( i will get the 30 guid firstly so i can clarify that ) after that, send one request for 10 of them to show them on first page of datatable, if user clicked on page two, server behind needs to send request for the other group of ten and returns me result to show on the table.
I tried to implement the structure below :
http://www.codeproject.com/Articles/359750/jQuery-DataTables-in-Java-Web-Applications#ServerSideProcessing
but it populates a table with the DataRepository ones with all of them, so with this point of view i can't use it dynamically as i totally requested.
The main need for this, XML return for many objects needs so long time.
So do you know any example link or tutorial such a need for this ?
Thank you for informations in advance!
#Hayra, thanks for providing the Code Project link to the JQuery-DataTable example, it is very helpful. This is something that I might implement soon.
What I understood from the example, the JQuery-DataTable keeps track for you specific parameters that will allow you to return the exact number of records. The specific parameters that you need are "iDisplayStart" and the iDisplayLength". The "iDisplayLength" is set when the user specifies 10 records per page and the iDisplayStart, will is set when the page number changes.
So look at the code in the Code Project example doGet Method, this section of the code returns only the subset of records back to your table.
JQueryDataTableParamModel param = DataTablesParamUtility.getParam(request);
if(companies.size()< param.iDisplayStart + param.iDisplayLength) {
companies = companies.subList(param.iDisplayStart, companies.size());
} else {
companies = companies.subList(param.iDisplayStart, param.iDisplayStart + param.iDisplayLength);
}
try {
JsonObject jsonResponse = new JsonObject();
jsonResponse.addProperty("sEcho", sEcho);
jsonResponse.addProperty("iTotalRecords", iTotalRecords);
jsonResponse.addProperty("iTotalDisplayRecords", iTotalDisplayRecords);
for(Company c : companies){
JsonArray row = new JsonArray();
row.add(new JsonPrimitive(c.getName()));
row.add(new JsonPrimitive(c.getAddress()));
row.add(new JsonPrimitive(c.getTown()));
data.add(row);
}
jsonResponse.add("aaData", data);
response.setContentType("application/Json");
response.getWriter().print(jsonResponse.toString());
} catch (JsonIOException e) {
e.printStackTrace();
response.setContentType("text/html");
response.getWriter().print(e.getMessage());
}
I hope this help
At first I misunderstood my problem and posted this question : Can someone explain me Cascading and FetchType lazy in Ektorp?
What I need to do: I need to save an Entity in couchdb and then have way to read it and potentially ignore some fields.
So I came up with this solution: I create a show function that delete fields from an object and then send it back.
function(doc, req) {
var result = doc;
var ignore = JSON.parse(decodeURIComponent(req.query.ignore)); //this is an array of field names
for (var i = 0, j = ignore.length; i < j; i++) {
if (result[ignore[i]]) {
delete result[ignore[i]];
}
}
return {
body : JSON.stringify(result),
headers : {
"Content-Type" : "application/json"
}
};
}
I have the same function but reversed in which the object keeps the fields I tell the function to keep.
Is there a better way to do this?
I also want to use Ektorp to call this but it allows me to only call Views. Right now I am forced to manage the http request myself. Is there a way to avoid this?
Right now this is the code I must use, but I would like to use Ektorp to do this.
HttpClient httpClient = new StdHttpClient.Builder().url("http://localhost:5984").build();
CouchDbInstance dbInstance = new StdCouchDbInstance(httpClient);
CouchDbConnector db = new StdCouchDbConnector("mydatabase", dbInstance);
db.createDatabaseIfNotExists();
String[] forget = new String[] { "field_to_ignore" };
String uri = "/mydatabase/_design/mydesigndoc/_show/ignorefields/mydocid?ignore=" + URLEncoder.encode(Json.stringify(Json.toJson(forget)), "UTF-8");
System.out.println(uri);
HttpResponse r = db.getConnection().get(uri);
String stuff = new Scanner(r.getContent()).useDelimiter("\\A").next();
System.out.println(stuff);
A show function isn't a terrible idea, from a CouchDB point of view. Ektorp may not support them, presumably because they're not hugely used, but Ektorp's open-source and on Github; you could easily just add this functionality, especially since you already have the basics of a working implementation of it.
Alternatively you could just build a view that does this for a given set of fields. You can't really parameterize this though, so you'd need well-defined sets of fields you know beforehand.
Finally I'd suggest either pulling the whole document and not worrying about it (unless you're in an extremely hugely bandwidth-limited situation it's probably not going to matter), or splitting the document into the constituent parts you're querying for and requesting them independently, if that's definitely the unusual case.
I am working on application with jsp, jstl and jsf for my college project, thats being said, I am as well very new to jsf.
Everything is going great so far. However, I seems to have a problem figuring out how to do redirect from managed bean to page with dinamyc parameters.
For example article.jsp?article_id=2
Can somebody tell me how it is done ?
I been trying to use somethinng like
FacesContext.getCurrentInstance().getExternalContext().dispatch("faces/article.jsp2?article_id=" + articleId);
But get error:
javax.servlet.ServletException: #{postComment.postClick}: javax.faces.FacesException: javax.servlet.ServletException: javax.faces.component.UIViewRoot cannot be cast to com.sun.faces.application.StateManagerImpl$TreeNode
javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
I been trying to use
response.sendRedirect("faces/article.jsp2?article_id=" + articleId);
return;
But again getting an error.
javax.servlet.ServletException: Cannot forward after response has been committed
javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
Can somebody please tell me how do i redirect from managed java bean when working with jsf ?
Bellow is my code (maybe something wrong with that and thats why redirect not working).
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
String articleId = request.getSession().getAttribute("article_id").toString();
//String articleId = request.getParameter("article_id");
String authorName = request.getSession().getAttribute("user_name").toString();
java.util.Calendar calendar = java.util.Calendar.getInstance();
String commentDate = String.valueOf(calendar.get(java.util.Calendar.DAY_OF_MONTH)) + ".";
commentDate += String.valueOf(calendar.get(java.util.Calendar.MONTH)) + ".";
commentDate += String.valueOf(calendar.get(java.util.Calendar.YEAR));
ArrayList error = new ArrayList();
if(commentName.contains("<"))
{
error.add("Comment name contains illegal characters");
}
if(commentBody.isEmpty() && commentBody.contains("<script"))
{
error.add("Your message body contains illegal characters");
}
if(error.size() > 0)
{
request.getSession().setAttribute("error", error);
error.clear();
FacesContext.getCurrentInstance().getExternalContext().dispatch("article.jsp2?article_id=" + articleId);
}
else
{
Comment comment = new Comment();
comment.setCommentAuthor(authorName);
comment.setCommentBody(commentBody);
comment.setCommentDate(commentDate);
comment.setCommentName(commentName);
comment.setArticleId(articleId);
DisplayArticleIO addComment = new DisplayArticleIO();
addComment.postComment(comment);
// FacesContext.getCurrentInstance().getExternalContext().dispatch("faces/article.jsp2?article_id=" + articleId);
response.sendRedirect("faces/article.jsp2?article_id=" + articleId);
return;
}
Thank you in advance.
In case some one will run into same problem.
That's what solved my problem:
FacesContext.getCurrentInstance().getExternalContext().redirect("article.jsp?article_id=" + articleId);
Why are you using dispatch in one place and redirect in the other? This isn't the source of the problem - not returning after sending responses, however, is. Other then that, if you don't mind, I have a few friendly suggestions:
You can use DateFormat to return the comment date as you want it (it will be much cleaner).
If the errors ArrayList only contains Strings, use generics (ArrayList<String>).
What are you doing with the errors?
Your sanitation of the commentName is very dangerous. You should use whitelisting instead of blacklisting - define what you wish to accept in a comment and block everything else. Right now someone could insert an <img> tag with a src pointing to a cookie stealing page which would result in a session hijack.
After changing the dispatch to a redirect add a return below it (you should always do this. Not doing this could result in what you're seeing right now, which is that you've already sent a response somewhere else, but since you haven't returned you've reached a place where you're trying to send another).
Basically, something is already sending output to the client before you make the call to response.sendRedirect(). Once something has been sent to the browser you can't redirect or forward them to a different place.
In general, any scenarios that might result in a redirect or a forward should be handled as early as possible in the request context to insure the redirect happens before you send any data to the client. Are you doing something like calling this code via a tag in the view?
FacesContext.getCurrentInstance().getExternalContext().redirect("http://www.myUrl.com");
René