How to change the URL that contains "#!" to "d/" in Java? - java

Ok, here is my problem. I am building the Ajax Web app & to make my webapp to be seen by Google spider, I need to use the url that contain hashbang "#!". For example, my url could be like this:
mydomain.com/#!getCustomer
mydomain.com/#!getOrder
....
These url look pretty ugly & beside Google adword does not allow # in the url so I can't advertise my url in Goolge.
Thus, I want that everytime user go to the above link, the system will change "#!" to "d/", so that users will see these:
mydomain.com/d/getCustomer
mydomain.com/d/getOrder
....
Note: even the url doesn't contain "#!", but the system still be able to let Google spider to index my website.
So, I use FilterServlet to do that:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String fullURLQueryString = getFullURL(httpRequest);
System.out.println(fullURLQueryString); // test url
if ((fullURLQueryString != null) && (fullURLQueryString.contains("#!"))) {
fullURLQueryString=fullURLQueryString.replace("#!", "d/");
request.getRequestDispatcher(fullURLQueryString).forward(request, response);
}
}
However, the system does not recognize the part "#!" when capturing the fullURLQueryString
So the System.out.println(fullURLQueryString); only print out the mydomain.com & it ignores completely the part #!getCustomer or #!getOrder.
Did i do anything wrongly here?
Can you fix it?

You do not have to use #!, if your web application doesn't use client-side generated content. If your URLs do not currently contain #, this functionality is of no interest for your.
In typical scenario in which this is useful user goes to page: http://example.com/#page1.
The browser requests http://example.com/ (notice #page1 is not in the request). After the page is loaded, client side JavaScript examines the part after # and downloads additional content.
Google bots do not support JavaScript and cannot download any additional content. For them, every page http://example.com/#page1, http://example.com/#page2 ... looks the same.
To fix this, #! syntax was introduced. You can learn more about it here.

You cannot do this server-side because browsers never send the URL fragment (the # and everything after it) to the server. You can do this replacement only with client-side JavaScript:
if (location.href.match(/\/#!/)) {
location.replace(location.href.replace(/\/#!/, '/d/'));
}

You should be constructing your URLs with the URL class (not a String).
Here is the official Java 8 Documentation:
http://docs.oracle.com/javase/8/docs/api/java/net/URL.html

The problem is with your getFullURL() method. Instead you should use getRequestURL().

Related

Java EE - Show page based on internal business logic

I'm implementing an enterprise application with Java EE on Glassfish server. I need to my application to execute some logic to show the proper output for a specific subset of URLs.
Problem description:
My web pages folder has this structure:
Web Pages
Protected
- CorrectPage.xhtml
- A.xhtml
- B.xhtml
- Index.xhtml
I want the user to access the URL:
/Protected/CorrectPage.xhtml
But the user must not be able to access the following URLs:
/Protected/A.xhtml
/Protected/B.xhtml
When the URL /Protected/CorrectPage.xhtml is entered I want to execute some logic and depending on the outcome of this logic I want to show either A.xhtml, or B.xhtml, without any visible URL changes (redirects).
Solutions tried so far:
I thought about using a servlet mapped to /Protected/*.xhtml while leaving the Faces Servlet deal with any other URL in my application.
and having :
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if(*Requested URL is /Protected/CorrectPage.xhtml*) {
if(logic())
*Show A.xhtml*
else
*Show B.xhtml*
} else
*Show 404*
My issue is that I don't know how to implement the Show A.xhtml. I basically want to print to the client my xhtml page.
I also thought about solving this last issue by using the response PrintWriter.
PrintWriter pw = response.getWriter();
But than again this doesn't solve my issue since I don't know how to print the xhtml file while also having the evaluation of the expression language contained in it.
Conclusion
Any help is extremely appreciated. Even if that means changing something in the structure I proposed. Naturally if the creation of a servlet isn't the correct solution for my issues I will leave that track.
I'm interested only in the outcome the user will experience.
Thanks in advance
You may use request.getRequestDispatcher("/protected/page[A|B]").forward(request, response)

How to download file from web site having liferay portlet using java code

i'm trying to download a file from a site , this site has a life ray server
i have been reading to much about but all describe how to configure a server not how to read from , all examples i saw has HTTPServletRequest which needs a request input how can i transfer a URL to a request ,from where to start at least .
in other words :i have the URL , in the webpage i select a date and a download like is generated , how can i make it down in java ????
i tried this:
HttpServletRequest request = PortalUtil.getHttpServletRequest(PortletRequest);
so how to link my URL to PortletRequest
If you have the URL of the download the only thing you need is to perform a client request against that URL.
First thing you should try to be sure that the URL you have is the one that will give you the expected results is try to paste it in a new browser window and verify that the download starts.
Then, if you want to perform that download through Java you can do very easily using the URL and URLConnection (HttpURLConnection in this case) classes:
String urlString = "..."; // Your URL
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if (conn.getResponseCode() == 200) {
InputStream stream = conn.getInputStream();
// Read the data from the stream
}
You could also do the same using Apache HTTP Client.
Note: PortalUtil.getHttpServletRequest(...) is used internally by Liferay and you won't have any access to that API if you are doing a client request.
If you're writing a portlet, by design you don't get access to the HttpServletRequest.
What you can do is to utilize the "resource-serving" lifecycle phase of a portlet. There you get access to a ResourceRequest and ResourceResponse object. Those objects behave almost like a HttpServletRequest/-Response object
As you don't name the framework that you're using: javax.portlet.GenericPortlet.serveResource() is the method that you want to override in the pure JSR-286 API.
On the UI side, <portlet:resourceURL/> will provide the URL to your portlet's resource handling method.
This should provide you with enough google-food to find tutorials on how to implement different lifecycle phases - I can't judge the required level of detail you need. Note that Liferay has quite a few sample portlets that you can utilize as a source for sample code.
Edit: Following your comment below, let me give you some pseudo code (just typed here, never compiled/run):
on a jsp frontend, e.g. view.jsp:
Download File
Then, in your portlet, assuming you're implementing javax.portlet.GenericPortlet in one way or another (e.g. indirectly through Liferay's MVCPortlet or any other superclass):
public class MyPortlet extends GenericPortlet {
....
#Override
public void serveResource(ResourceRequest request, ResourceResponse response) {
// implement the file streaming here,
// use ResourceResponse the way you find illustrated
// in samples for HttpServletResponse
}

How to secure URL parameters in java

Sample URL http://dineshlingam.appspot.com/guestbook?name=xxx&skills=zzz
Sample Code
public class GuestbookServlet extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException
{
String userName = req.getParameter("name");
String userSkills = req.getParameter("skills");
if(userName != null && userSkills != null)
{
res.setContentType("text/plain");
res.getWriter().println("Name : " + userName + ", Skills : " + userSkills);
}
else
res.sendRedirect(req.getRequestURI());
}
}
I am manually enter this URL to web browser.
How to secure parameters value.
Give me any one suitable example. Because I don't know the java concept and google-app-engine concept.
Really I don't know the SSL. So please I need detailed explanation of SSL with Example.
I am using eclipse to develop my application. Please help me. Thanks.
Your code is a classic example of a page vunerable to a CSS (Cross-Site-Scripting) attack. Using HTTPS wont mitigate that. Instead you need to escape any input before adding it to the page.
For example by using StringEscapeUtils.escapeHtml() and StringEscapeUtils.escapeJavaScript() from the Apache Commons Lang library.
Using https does not secure url parameter by any mean. You have to put parameters either in header or body if you want to make it secure. However if you are making a call directly from browser for this you cant put it in header neither in body because it is a a GET request. +1 to nfechner for highlighting XSS issue in your code.
For your problem here are the possible workaround with https:
Instead of GEt call use a POST call by putting this search in separate form in your page and use HTTPS on top of that.
If you want to use GET request you have to put the parameters in Headers, make a search page, When user hits the search button, make ajax call to above resource by passing it into header using https call.

redirecting between java servlets from url containing #

Hey,
Maybe the title is not the best choice, but I really don't know how to better describe the problem.
The thing is when you point your browser to url that contains #
http://anydomain.com/test/elsem/1234#dogeatdog
and for some reason (ie. there is a business logic) you want to redirect to other page
http://anydomain.com/test/els/1234
the #dogeatdog will be added to new url.
I found this behavior while developing wicket app, but just now I tested it with simple pure java servlet. Can someone explain it to me?
Here is the code just in case I'm doing something wrong:
private void process(HttpServletRequest req, HttpServletResponse res)
{
res.setContentType("text/plain");
try
{
HttpSession session = req.getSession();
Object as = session.getAttribute("as");
if (as == null)
{
log.info("redirecting");
session.setAttribute("as", 1);
res.sendRedirect("/test/");
}
else
{
log.info("writing");
PrintWriter out = res.getWriter();
out.write("after redirect "+as);
out.flush();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
Hash fragments (#a_hash_fragment) never leave the browser, they are not part of HTTP request.
What the web server gets in this case is GET /test/elsem/1234, and it responds with redirect 3xx code and the new url /test/els/1234, which your browser picks and appends #dogeatdog. Makes sense now?
UPDATE: Thanks to Zack, here's a W3C document that exactly explains how this (should) work:
http://www.w3.org/Protocols/HTTP/Fragment/draft-bos-http-redirect-00.txt
From the sendRedirect Javadoc:
Sends a temporary redirect response to the client using the specified
redirect location URL. This method can accept relative URLs; the
servlet container must convert the relative URL to an absolute URL
before sending the response to the client. If the location is relative
without a leading '/' the container interprets it as relative to the
current request URI. If the location is relative with a leading '/'
the container interprets it as relative to the servlet container root.
Because of repetitive use of "relative" in the Javadoc, I suspect the new URL is using what it can from the old URL and then building from there...
In the brief amount of what I've read, forwarding should be used if possible instead of redirect.
See this for a good explanation of forward verses redirect.
See this for straight-forward examples of forwarding requests to Servlets or JSPs.
Of course, with forwarding, the original URL will remain intact so that may not be what you're looking for...
EDIT
With information from milan, I found some more information regarding URL fragments (the stuff after "#" - I didn't know that was their official name until corresponding with milan).
There's another SOF post that has some good information concerning this and possibly the best answer: URL Fragment and 302 redirects
I have "+1'd" milan for giving good direction on this...

Supporting Sessions Without Cookies in Tomcat

I am currently running an application with the following properties:
Java-based with Spring and Acegi
Running on Tomcat 5
I need the ability to support user sessions without cookies. Could someone please point me in the right direction.
Thank you.
The complete answer to this question is a combination of all your responses, so I'm going to summarize:
There is no need to set cookies="false" in the context.xml file. The ideal functionality is for tomcat to use it's url-based session identification, which will be used by default if cookies are not supported by the user.
When a user doesn't have cookies enabled, tomcat will identify the session by the "JSESSIONID" parameter from the url of the request. A couple sample urls are as follows
http://www.myurl.com;jsessionid=123456AFGT3
http://www.myurl.com;jsessionid=123456AFGT3?param1=value&param2=value2
Notice how the session id is not part of the url query string (this is a j2ee standard)
In order to ensure the jsessionid parameter gets appended to all your request URLs, you can't have plain url references. For example, in JSTL, you have to use < c:url>. The servlet engine will then automatically append the jsessionid to the url if it is necessary. Here's an example:
<%--this is bad:--%>
< a href="page.html">link< / a>
<%--this is good:--%>
< a href="< c:url value='page.html'/>">link< / a>
See http://tomcat.apache.org/tomcat-5.5-doc/config/context.html.
In a file META-INF/context.xml,
<?xml version='1.0' encoding='UTF-8'?>
<Context path='/myApplicationContext' cookies='false'>
<!-- other settings -->
</Context>
You could track by IP address, but proxy servers (and NAT?) could mess you up.
You could force all URLs to have the session as a parameter, and all forms as a hidden field. Maybe a custom tag for generating URLs could help here, but I've not done much work with taglibs.
You will need to consider security - people might email links to someone else with the session id in it, so you will want to have an IP address check for each access to check that the address matches the session.
As matt b commented this should work out of the box (tomcat will try cookies, and if that fails fall back on encoding the session in the url). However, this will not work if you create a 'plain' link yourself - always use a method like JSTL's so tomcat can add the tracking parameter to all urls.
Best way is to use URL rewriting . So, when you use request.getSession() ,the container will send "Set-Cookie" header for session-id in HTTP-response as well as session-id appended to URL (but you must use response.encodeURL(session_info) for url rewriting).
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter pw=resp.getWriter();
HttpSession session=req.getSession();
pw.println("<html><body>");
pw.println("Click");
pw.println("</body></html>");
}

Categories

Resources