Link to home
Start Free TrialLog in
Avatar of Hokester
Hokester

asked on

Escaped & in java servlet

I have many java servlets that create a html link using the a form like

http://mydomain.com?value1=answer1&value2=answer2&value3=answer3

To be proper html for the validator this should look like

http://mydomain.com?value1=answer1&value2=answer2&value3=answer3

How do you write this in a servlet so that when you use
HttpServletRequest.getParameter(value1) you will get a proper value

If i Echo all of the parameters for the HttpServletRequest, they look like
amp;value1=answer1
amp;value2=answer2
amp;value3=answer3

I would have preferred the servlet request to handle the escaped Ampersand.
Avatar of Mick Barry
Mick Barry
Flag of Australia image

You can use replaceAll() method in string class

> To be proper html for the validator this should look like
> http://mydomain.com?value1=answer1&value2=answer2&value3=answer3

not sure thats correct though.
your curreent url looks fine

> I would have preferred the servlet request to handle the escaped Ampersand.

It *is* handling them correctly, it expects & and not &
Avatar of Hokester
Hokester

ASKER

The problem is that getParameter expects & but & is not valid html syntax according to the w3c standards. If you use & in a link, w3c says you do not have valid syntax and instead suggest to use & in the link.
> The problem is that getParameter expects & but & is not valid html syntax according to the w3c standards.

not sure I understand. what are you basing that on?
In my example using the encoded ampersand:
http://mydomain.com?value1=answer1&value2=answer2&value3=answer3

If i said

String result = request.getParameter("value1");

result would be null because value1 is not a parameter;

If i said
String result = request.getParameter("amp;value1"); // Note that is amp;, not &

result would be answer 1.

It seems wrong that the html standard requires the parameters to be separated by & , however the servlet parameters act like & is wrong and & is truly how they should be separated.  

I 'could' change all of my getParameter function calls to have "amp;" in front of the field, but it seems like there should be a better/easier way.
> It seems wrong that the html standard requires the parameters to be separated by &

why do you think it does. Can you show me a pages that does that?

> however the servlet parameters act like & is wrong and & is truly how they should be separated.  

& *is* how they should be seperated.
I suspect you have misunderstood the standard, can you post the section that you are referring to.
I've created an example
http://ericpastoor.homeip.net/foo.html

The example first has a link using only the & symbol

The second link uses &

Here is the link for the w3c validator
http://validator.w3.org/

There you can try and validate this test file and you will see that the single & is an error.
This is the link w3c provides about & in urls.
http://www.htmlhelp.com/tools/validator/problems.html#amp
And both work the same :)  Its the job of the browser to decode & -> &
ie. by the time it gets to your servlet & will already have been converted to &
I realize both work the same, however only the & is valid html syntax. That makes the & the right way to write a link. Does the HttpServletRequest have a function that handles the valid syntax? When the link gets to my servlet, and the HttpServletRequest.getParameter function analyzes the link, it analyzes the link as &, not &. It seems wrong that the HttpServletRequest expects invalid html syntax/ does not handle valid syntax properly.
> Does the HttpServletRequest have a function that handles the valid syntax?

It doesn't need to, it should have already been converted by the timne it reaches the server.
"With HTML, the browser translates "&" to "&" so the Web server would only see "&" and not "&" in the query string of the request."
I realize that you think the webser should see & and not & but it doesn't work that way. My tomcat server sees &
It therefore thinks that the delimeter is & and then amp; is the beginning of the first parameter.

I found this about the API.
The Servlet API has a getParameter method in the HttpServletRequest class that returns the GET or POST value for the name you supply.

    * The HTTP GET request handles name and value pairs as part of the URL. The getParameter method parses the URL passed in, retrieves the name=value pairs deliminated by the ampersand (&) character, and returns the value.

It doesn't say anything about properly handling &
then the problem is in the browser, what browser are you using?

> It doesn't say anything about properly handling &

and it shouldn't, it expects &


I've tried firefox, IE, Opera, and Safari. Any time I use & in the link, the link still works as & as described above, but when it gets to the servlet, the HttpServletRequest sees it as &parameter1=value1 instead of &parameter1=value1
Appears to interpreted fine here in firefox and ie
It is interpreted fine in the browser. It is when it gets to the java servlet code that it is not interpreted as & anymore, and shows up as &
the browser shouldn't be sending the &, its a html standard, not a http standard.
and it doesn't send it when i tested those pages here.
Are you checking those values as an HttpServletRequest object, not just in html?
clicking on it and seeing the resulting url being sent.

Which agress with what the html standard states, that the client should be converting them before sending to the server. It nothing to do with the server, it should be dealt with by the client. & is not a valid parameter seperator.
I wrote a simple jsp to show what I am talking about.

http://ericpastoor.homeip.net/ampersand.jsp?param1=answer1&param2=answer2&param3=answer3

If you click on that link you will see that the & is not handled correctly by HttpServletRequest getParameterNames or getParameter()

Here is the jsp code that is that page


<%@ page import="java.util.Enumeration"%>
<HTML>  
 <HEAD>
  <TITLE>Hello World</TITLE>
 </HEAD>  
 <BODY>
    <H1>Hello World</H1>
       Today is: <%= new java.util.Date().toString() %>
       <BR>    
       HttpServletRequest URL = <%=request.getRequestURL().toString()%>
       <BR>
       Query String = <%=request.getQueryString()%>
       <BR>
       <%
        Enumeration params = request.getParameterNames();
        String paramName = null;
        String[] paramValues = null;
        while (params.hasMoreElements())
        {
          paramName = (String) params.nextElement();
          paramValues = request.getParameterValues(paramName);
       %>
        Parameter name is "<%=paramName%>"
       <%      
         for (int i = 0; i < paramValues.length; i++)
          {
        %>
        , value <%=i%> is "<%=paramValues[i].toString()%>"
        <BR>
        <%
          }
        }
       
       %>
  </BODY>
</HTML>
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is bizarre
When I click on the link from what I just posted, here is the output
Hello World

Today is: Thu Mar 30 20:17:58 EST 2006
HttpServletRequest URL = http://ericpastoor.homeip.net/ampersand.jsp 
Query String = param1=answer1&param2=answer2&param3=answer3
Parameter name is "param3" , value 0 is "answer3"
Parameter name is "param2" , value 0 is "answer2"
Parameter name is "param1" , value 0 is "answer1"

Which is what I wanted, 10 minutes ago when I did that, it gave me this

Today is: Thu Mar 30 20:10:55 EST 2006
HttpServletRequest URL = http://ericpastoor.homeip.net/ampersand.jsp 
Query String = param1=answer1&param2=answer2&param3=answer3
Parameter name is "amp;param3" , value 0 is "answer3"
Parameter name is "amp;param2" , value 0 is "answer2"
Parameter name is "param1" , value 0 is "answer1"
sorry, don't have an answer for you there :)
I really don't know why this didn't work all this time and now it is. I'm not sure what changed, but it clearly works now. I can't figure out what happened, but at least here I can see that it can work as you have decribed. Thanks a ton for your help. I've increased your points to as much as I have to give.
Thanks!