Creating Friendly URLs

Hi to all =).

I've been searching the internet, but I've yet to find an appropriate place that answers my following qns with the technology I am using.

I would like to create a Friendly URL for eg: http://www.example.com/johnMcWell

Upon typing this url on the address bar, the web application will retrieve data from the database whose name is johnMcWell, and display it on the webpage. Same goes for other friendly urls such as

http://www.example.com/janePolier, http://www.example.com/teraJones

How should I do this? Could someone give me an example and which files I need to have or edit?

The technology i am using is entirely JSF, IDE is NetBeans5.5, Application Server 9.0

Thanks and I truely appreciate the help and replies to come! =)

[793 byte] By [justinlima] at [2007-11-26 13:50:48]
# 1

You can use a simple servlet for this.

Add a servlet which is mapped on the root which does a check on the URI and do the appropriate forward.

Basic example:public class FriendlyURLServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException

{

forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException

{

forward(request, response);

}

private void forward(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException

{

String pathInfo = request.getPathInfo(); // The path info. You might need this.

String url =...; // Build real URL based on the current request URI.

...

getServletContext().getRequestDispatcher(url).forward(request, response);

}

}

web.xml<servlet>

<servlet-name>FriendlyURLServlet</servlet-name>

<servlet-class>mypackage.FriendlyURLServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>FriendlyURLServlet</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

BalusCa at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Hi there,

I understand you are using a Servlet, and all urls will be directed to the FriendlyServlet using the web.xml codes.

However, I would like to ask if this Friendly Servlet can also act as a managed bean. Meaning to say that this Servlet is a managed-bean, which supports some JSF pages.

I think there is a major difference between the structure Managed-Beans and Servlets. Or is there a way to get passed?

public class FriendlyURLServlet extends HttpServlet {

private Person personObject;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException

{

forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException

{

forward(request, response);

}

private void forward(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException

{

String pathInfo = request.getPathInfo();

//With the pathInfo, I query the database and set the personObject attribute.

String url ="jsfPage.jsp"; // the servlet will forward to a JSF page that uses data from this personObject.

getServletContext().getRequestDispatcher(url).forward(request, response);

}

}

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

Strictly looking a backing bean is not intented for this kind of mapping actions. But you can just put the PersonObject in the sessionMap for example. In the backing bean you can access the sessionMap by FacesContext.getCurrentInstance().getExternalContext().getSessionMap(). Or use the requestMap or requestParameterMap if you want to keep it request scoped.

BalusCa at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

Hi there,

Many thanks for your reply. I do see where you are getting and I think its a possible way to solve the qns I asked.

Here are some further qns:

protected void ProcessRequest (Http..., Http...) {

....

String nextURL = "/faces/shop.jsp";

getServletContext().getRequestDispatcher(nextURL).forward(request, response);

.....

}

I did the above code, in my Servlet, however I got the following error:

[#|2007-01-02T03:21:23.760+0800|SEVERE|sun-appserver-pe9.0|javax.enterprise.system.container.web|_ThreadID=16;_ThreadName=httpWorkerThread-8080-0;_RequestID=3b53f3a8-c8f6-4e8e-ab48-57759aa531db;|ApplicationDispatcher[/web] Servlet.service() for servlet Faces Servlet threw exception

java.lang.NumberFormatException: For input string: "shop.jsp"at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

The above came as a surprise to me, as I don't understand how could a NumberFormatException occur. I suspect it is the getServletContext().getRequestDispatcher(nextURL).forward(request, response); which threw that error.

Could there be another way to forward it to another page?

And, how do I store an Object onto the SessionMap? Or is it there automatically already when I declare an object in the Servlet.

Thanks for the replies. I truely appreciate it.

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

Hi there, I tried to get the external context just like my code below... please see my comments below

public ShopController() {

System.out.println("We entered shopcontroller Constructor method");

//FacesContext.getCurrentInstance().getExternalContext().getSessionMap().clear();

FacesContext fc = FacesContext.getCurrentInstance();

FriendlyUrlServlet fus = (FriendlyUrlServlet) fc.getApplication().getVariableResolver().resolveVariable(fc, "FriendlyUrlServlet");

System.out.println("IS FUS EQUAL TO NULL? : " + fus==null); <--printed out false...

Shopdetails currentShop = fus.getCurrentShop(); <-- threw an exception saying NullPointerException *****

System.out.println("IS Current Shop EQUAL TO NULL? : " + currentShop==null);

//System.out.println(currentShop.getShopname());

//System.out.println("Laughter: " + context.getExternalContext().toString());

//context.responseComplete();

}

Why did Shopdetails currentShop = fus.getCurrentShop(); throw a null pointer exception? I suspect that the Servlet did not save the attribute, and when I led control over to the Managed Bean, the Servlet did not save the attribute "Shopdetails"...

How should I get passed this barrier? I would like to retrieve the Shopdetails Object which was stored in the FriendlyUrlServlet (a servlet) from a ShopController(a managed bean). How to do this?

Thanks

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

NumberFormatException: this is just an ordinary error in the JSF page. Nothing to do with servlets. Check your JSF and backing bean code.

Storing objects in SessionMap: I got awaked, in servlets you cannot directly access the ExternalContext. But there is a trick described somewhere on the web: http://wiki.apache.org/myfaces/AccessFacesContextFromServlet Check the getFacesContext() method. Then you can use getFacesContext().getExternalContext().getSessionMap(). In the backing bean just do FacesContext.getCurrentInstance().getExternalContext().getSessionMap().

This article also states the following:

In closing, I'm sure there may be better ways for doing this but more importantly, there are probably good reasons for not doing this at all and changing to Phase Listeners and staying within the JSF framework which I think is an important topic for continued discussion.

PhaseListeners cannot be used for URL mappings (as far, I cannot design such a PhaseListener in my brain directly), so I think you might go ahead with this approach.

Message was edited by:

BalusC

BalusCa at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

Hi,

First of all, I am really thankful for the advice you have given to me so far. I appreciate it, thanks.

I have read your thread and I actually wanted to know how I could access a Servlet From a ManagedBean. The other way round. The example you gave was to access a managedBean from a Servlet.

Could you advice me on this again? thanks...

I am new to JSF and don't really understand how to use PhaseListeners..

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

Hi,

First of all, I am really thankful for the advice you have given to me so far. I appreciate it, thanks.

I have read your thread and I actually wanted to know how I could access a Servlet From a ManagedBean. The other way round. The example you gave was to access a managedBean from a Servlet.

Could you advice me on this again? thanks...

I am new to JSF and don't really understand how to use PhaseListeners..

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9

> I have read your thread and I actually wanted to know

> how I could access a Servlet From a ManagedBean. The

> other way round. The example you gave was to access a

> managedBean from a Servlet.

This example was not to access a managed bean from a servlet. This just shows how to access the FacesContext in an ordinary servlet.

And .. Why should you want to access a servlet from a backing bean? I don't see any benefits in this.

BalusCa at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10

Hi,

The primary reason why I wanted to Access a Servlet From a ManagedBean is because of my need to create Friendly URLS. The following is my method so far which leads me to ask why I need to access a Servlet from a Managed Bean.

1. A person types in http://www.friendlyUrl.com/justinlim

2. Web.xml maps this URL pattern to FriendlyUrlServlet. This servlet extracts the word 'justinlim', searches the database for this person's data and stores all these data in an Object stored inside this Servlet.

3. This servlet redirects the user to a JSF page, backed by a backing bean (managed bean). Note that this JSF page is the first page which the user will see after typing the friendly URL. Step 2 was done by the Application Server invisible to the user.

4. The backing bean (managed bean) is suppose to ask the Servlet for the Person Object which it has extracted from the databse in Step 2 and store it as an attribute inside the managed bean. Now, this JSF page will also show data which reflects the friendly URL.

An example of Friendly URL which I am trying to create is something like http://www.friendster.com/36691010 (just an example.)

Is there a better way to do this through JSF? Thanks

justinlima at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11
You shouldn't store objects in a lazy servlet. I repeat: put it in the sessionMap of the FacesContext.
BalusCa at 2007-7-8 1:27:46 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...