Encoding and rewriting of URL - java

We use URL rewriting or cookies to maintain session across a web server and a browser because they communicate using HTTP protocol which is stateless in nature. Because of its stateless nature, server never recognizes any client(browser) whether it has made any request previously or not. We therefore need to maintain a unique identifier in between them.
When a browser (client) doesn't support cookies or cookies are disabled on the browser, the technique called URL rewriting is used and the sessionID needs to be encoded in the URL such as,
try
{
response.sendRedirect(response.encodeRedirectURL("index.jsp?param=value"));
}
catch(Exception e)
{
}
Regrading a normal link in JSP, I use the JSTL's <c:url> tag like,
<c:url value="Category.htm" var="url">
<c:param name="id" value="${row.category.catId}"/>
</c:url>
<a href="${url}"
name="catId${row.category.catId}"
title="Click to view the details.">${row.category.catName}
</a>
It is embedded within a <c:forEach> loop.
But if the browser supports cookies or session tracking is turned off, URL encoding is unnecessary and it doesn't take place.
So, in that case, what if a URI or a query contains special characters like +, &, #?
They need to be encoded and if a URI and a query string were encoded separately, would URL rewriting automatically done, in case cookies are disabled or not supported by a browser like?
URI uri = new URI(
"http",
null,
request.getServerName(),
request.getServerPort(), "/WebApp/index.jsp",
"param="+URLEncoder.encode("some value#+", "UTF-8"), null);
String uriString = uri.toASCIIString();
and in this case the parameter param needs to be decoded while retrieving,
out.println(URLDecoder.decode(request.getParameter("param"), "UTF-8")");
What about the URL rewriting in this case, I'm unsure whether it is done by the Servlet Container or to be handled separately on our own.
One additional thing, while using RequestDispatcher, <jsp:forward page="index.jsp"/> and <jsp:include page="template.jsp"/>, is it necessary to take care of URL encode like?
try
{
RequestDispatcher requestDispatcher=
request.getRequestDispatcher(response.encodeURL("index.jsp?param=value"));
requestDispatcher.forward(request, response);
}
catch(Exception e)
{
}
and I always use <c:url> with the form's action attribute like (regarding Spring),
<c:url value="${param.url}" var="url">
<c:param name="id" value="${param.id}"/>
</c:url>
<form:form action="${url}" id="dataForm" name="dataForm" method="post" commandName="someBean">
.
.
.
</form:form>
It refers to the current URL. Is it really required (even though I'm not supplying any parameter(s))?

About the last question, experience with Spring 3.0.5 tells that you can omit the action attribute in form:form , it will user the current URL and append the session ID parameter in case cookies are not used.
Related to this, is it possible to use a shorter syntax, something like <form:form action="<c:url value="foo"/>" ... ?
This exact syntax does not work, as tags can not be nested this way. The usage of an extra variable is a bit too long to my taste.

Related

HTML : Form does not send UTF-8 format inputs

I've visited each one of the questions about UTF-8 encoding in HTML and nothing seems to be making it work like expected.
I added the meta tag : nothing changed.
I added the accept-charset attribute in form : nothing changed.
JSP File
<%# page pageEncoding="UTF-8" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Editer les sous-titres</title>
</head>
<body>
<form method="post" action="/Subtitlor/edit" accept-charset="UTF-8">
<h3 name="nameOfFile"><c:out value="${ nameOfFile }"/></h3>
<input type="hidden" name="nameOfFile" id="nameOfFile" value="${ nameOfFile }"/>
<c:if test="${ !saved }">
<input value ="Enregistrer le travail" type="submit" style="position:fixed; top: 10px; right: 10px;" />
</c:if>
Retour à la page d'accueil
<c:if test="${ saved }">
<div style="position:fixed; top: 90px; right: 10px;">
<c:out value="Travail enregistré dans la base de donnée"/>
</div>
</c:if>
<table border="1">
<c:if test="${ !saved }">
<thead>
<th style="weight:bold">Original Line</th>
<th style="weight:bold">Translation</th>
<th style="weight:bold">Already translated</th>
</thead>
</c:if>
<c:forEach items="${ subtitles }" var="line" varStatus="status">
<tr>
<td style="text-align:right;"><c:out value="${ line }" /></td>
<td><input type="text" name="line${ status.index }" id="line${ status.index }" size="35" /></td>
<td style="text-align:right"><c:out value="${ lines[status.index].content }"/></td>
</tr>
</c:forEach>
</table>
</form>
</body>
</html>
Servlet
for (int i = 0 ; i < 2; i++){
System.out.println(request.getParameter("line"+i));
}
Output
Et ton père et sa soeur
Il ne sera jamais parti.
I added the meta tag : nothing changed.
It indeed doesn't have any effect when the page is served over HTTP instead of e.g. from local disk file system (i.e. the page's URL is http://... instead of e.g. file://...). In HTTP, the charset in HTTP response header will be used. You've already set it as below:
<%#page pageEncoding="UTF-8"%>
This will not only write out the HTTP response using UTF-8, but also set the charset attribute in the Content-Type response header.
This one will be used by the webbrowser to interpret the response and encode any HTML form params.
I added the accept-charset attribute in form : nothing changed.
It has only effect in Microsoft Internet Explorer browser. Even then it is doing it wrongly. Never use it. All real webbrowsers will instead use the charset attribute specified in the Content-Type header of the response. Even MSIE will do it the right way as long as you do not specify the accept-charset attribute. As said before, you have already properly set it via pageEncoding.
Get rid of both the meta tag and accept-charset attribute. They do not have any useful effect and they will only confuse yourself in long term and even make things worse when enduser uses MSIE. Just stick to pageEncoding. Instead of repeating the pageEncoding over all JSP pages, you could also set it globally in web.xml as below:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
As said, this will tell the JSP engine to write HTTP response output using UTF-8 and set it in the HTTP response header too. The webbrowser will use the same charset to encode the HTTP request parameters before sending back to server.
Your only missing step is to tell the server that it must use UTF-8 to decode the HTTP request parameters before returning in getParameterXxx() calls. How to do that globally depends on the HTTP request method. Given that you're using POST method, this is relatively easy to achieve with the below servlet filter class which automatically hooks on all requests:
#WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
#Override
public void init(FilterConfig config) throws ServletException {
// NOOP.
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
#Override
public void destroy() {
// NOOP.
}
}
That's all. In Servlet 3.0+ (Tomcat 7 and newer) you don't need additional web.xml configuration.
You only need to keep in mind that it's very important that setCharacterEncoding() method is called before the POST request parameters are obtained for the first time using any of getParameterXxx() methods. This is because they are parsed only once on first access and then cached in server memory.
So e.g. below sequence is wrong:
String foo = request.getParameter("foo"); // Wrong encoding.
// ...
request.setCharacterEncoding("UTF-8"); // Attempt to set it.
String bar = request.getParameter("bar"); // STILL wrong encoding!
Doing the setCharacterEncoding() job in a servlet filter will guarantee that it runs timely (at least, before any servlet).
In case you'd like to instruct the server to decode GET (not POST) request parameters using UTF-8 too (those parameters you see after ? character in URL, you know), then you'd basically need to configure it in the server end. It's not possible to configure it via servlet API. In case you're using for example Tomcat as server, then it's a matter of adding URIEncoding="UTF-8" attribute in <Connector> element of Tomcat's own /conf/server.xml.
In case you're still seeing Mojibake in the console output of System.out.println() calls, then chances are big that the stdout itself is not configured to use UTF-8. How to do that depends on who's responsible for interpreting and presenting the stdout. In case you're using for example Eclipse as IDE, then it's a matter of setting Window > Preferences > General > Workspace > Text File Encoding to UTF-8.
See also:
Unicode - How to get the characters right?
Warm up
Let me start by saying the universal fact which we all know that computer doesn't understand anything but bits - 0's and 1's.
Now, when you are submitting a HTML form over HTTP and values travel over the wire to reach destination server then essentially a whole lot of bits - 0's and 1's are being passed over.
Before sending the data to the server, HTTP client (browser or curl etc.) will encode it using some encoding scheme and expects server to decode it using same scheme so that server knows exactly what client has sent.
Before sending response back to the client, server will encode it using some encoding scheme and expects client to decode it using same scheme so that client knows exactly what server has sent.
An analogy for this can be - I am sending a letter to you and telling you whether it is written in English or French or Dutch, so that you will get exact message as I intended to send you. And while replying to me you will also mention in which language I should read.
Important take away is that the fact that when data is leaving the client it will be encoded and same will be decoded at server side, and vice-versa. If you do not specify anything then content will be encoded as per application/x-www-form-urlencoded before leaving from client side to server side.
Core concept
Reading warm up is important. There are couple of things you need to make sure to get the expected results.
Having correct encoding set before sending data from client to server.
Having correct decoding and encoding set at server side to read request and write response back to client (this was the reason why you were not getting expected results)
Ensure that everywhere same encoding scheme is used, it should not happen that at client you are encoding using ISO-8859-1 and at server you are decoding using UTF-8, else there will be goof-up (from my analogy, I am writing you in English and you are reading in French)
Having correct encoding set for your logs viewer, if trying to verify using log using Windows command-line or Eclipse log viewer etc. (this was a contributing reason for your issue but it was not primary reason because in the first place your data read from request object was not correctly decoded. windows cmd or Eclipse log viewer encoding also matters, read here)
Having correct encoding set before sending data from client to server
To ensure this, there are several ways talked about but I will say use HTTP Accept-Charset request-header field. As per your provided code snippet you are already using and using it correctly so you are good from that front.
There are people who will say that do not use this or it is not implemented but I would very humbly disagree with them. Accept-Charset is part of HTTP 1.1 specification (I have provided link) and browser implementing HTTP 1.1 will implement the same. They may also argue that use Accept request-header field's "charset" attribute but
Really it is not present, check the Accept request-header field link I provided.
Check this
I am providing you all data and facts, not just words, but still if you are not satisfied then do following tests using different browsers.
Set accept-charset="ISO-8859-1" in your HTML form and POST/GET form having Chinese or advanced French characters to server.
At server decode the data using UTF-8 scheme.
Now repeat same test by swapping client and server encoding.
You will see that none of times you were able to see the expected characters at server. But if you will use same encoding scheme then you will see expected character. So, browsers do implements accept-charset and its effect kicks-in.
Having correct decoding and encoding set at server side to read request and write response back to client
There are hell lot of ways talked about that you can do to achieve this (sometime some configuration may be required based on specific scenario but below solves 95% cases and holds good for your case as well). For example:
Use character encoding filter for setting encoding on request and response.
Use setCharacterEncoding on request and response
Configure web or application server for correct character encoding using -Dfile.encoding=utf8 etc. Read more here
Etc.
My favorite is first one and will solve your problem as well - "Character Encoding Filter", because of below reasons:
All you encoding handling logic is at one place.
You have all the power through configuration, change at one place and everyone if happy.
You need not to worry that some other code may be reading my request stream or flushing out the response stream before I could set the character encoding.
1. Character encoding filter
You can do following to implement your own character encoding filter. If you are using some framework like Springs etc. then you need not to write you own class but just do the configuration in web.xml
Core logic in below is very similar to what Spring does, apart from a lot of dependency, bean aware thing they do.
web.xml (configuration)
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>
com.sks.hagrawal.EncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
EncodingFilter (character encoding implementation class)
public class EncodingFilter implements Filter {
private String encoding = "UTF-8";
private boolean forceEncoding = false;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
if(forceEncoding){ //If force encoding is set then it means that set response stream encoding as well ...
response.setCharacterEncoding(encoding);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String encodingParam = filterConfig.getInitParameter("encoding");
String forceEncoding = filterConfig.getInitParameter("forceEncoding");
if (encodingParam != null) {
encoding = encodingParam;
}
if (forceEncoding != null) {
this.forceEncoding = Boolean.valueOf(forceEncoding);
}
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
}
2. ServletRequest.setCharacterEncoding()
This is essentially same code done in character encoding filter but instead of doing in filter, you are doing it in your servlet or controller class.
Idea is again to use request.setCharacterEncoding("UTF-8"); to set the encoding of http request stream before you start reading the http request stream.
Try below code, and you will see that if you are not using some sort of filter to set the encoding on request object then first log will be NULL while second log will be "UTF-8".
System.out.println("CharacterEncoding = " + request.getCharacterEncoding());
request.setCharacterEncoding("UTF-8");
System.out.println("CharacterEncoding = " + request.getCharacterEncoding());
Below is important excerpt from setCharacterEncoding Java docs. Another thing to note is you should provide a valid encoding scheme else you will get UnsupportedEncodingException
Overrides the name of the character encoding used in the body of this
request. This method must be called prior to reading request
parameters or reading input using getReader(). Otherwise, it has no
effect.
Wherever needed I have tried best to provide you official links or StackOverflow accepted bounty answers, so that you can build trust.
Based on your posted output it seems that the parameter is sent as UTF8 and later the unicode bytes of the string are interpreted as ISO-8859-1.
Following snippet demonstrates your observed behavior
String eGrave = "\u00E8"; // the letter è
System.out.printf("letter UTF8 : %s%n", eGrave);
byte[] bytes = eGrave.getBytes(StandardCharsets.UTF_8);
System.out.printf("UTF-8 hex : %X %X%n",
bytes[0], bytes[1], bytes[0], bytes[1]
);
System.out.printf("letter ISO-8859-1: %s%n",
new String(bytes, StandardCharsets.ISO_8859_1)
);
output
letter UTF8 : è
UTF-8 hex : C3 A8
letter ISO-8859-1: è
For me the form send the correct UTF8 encoded data, but later this data is not treated as UTF8.
edit Some other points to try:
output the character encoding your request has
System.out.println(request.getCharacterEncoding())
force the usage of UTF-8 to retrieve the parameter (untested, only an idea)
request.setCharacterEncoding("UTF-8");
... request.getParameter(...);
You can try to write that on .jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"%>
problem resolved for me with that.
You can use Strings related to ISO in your charset and pageEncoding definations in your JSP code.
Like charset="ISO-8859-1" and pageEncoding="ISO-8859-1".
There is a bug in tomcat that may trapped you. The first-filter defines the encoding the request is based on.
Every other filter or servlet behind the first-filter can not change the encoding of the request anymore.
I do not think this bug will be fixed in the future because the current applications may rely on the encoding.
resp.setContentType("text/html;charset=UT-8");

How to set URL anchor (hash) in servlets?

Simple question! Don't know why Google doesn't know the answer!
In a Java servlet, how can I set the URL anchor (hash) when returning to the user?
The URL anchor is handled by the browser only and never even reaches the server (it's not part of the request).
What this means is that server-side, either in a servlet as you propose or with any other server-side technology (e.g. PHP), you can redirect to an URL which has the URL anchor set, but you cannot check if an URL anchor was provided in the request you are currently processing.
This limitation prevents you from setting the URL anchor while keeping the rest of the URL unchanged, because the server has no way to differentiate between the address with and without the URL anchor.
So, this, you can do: the canonical address to this answer is this
http://stackoverflow.com/a/27988314/4402557
but the server redirects it to this
http://stackoverflow.com/questions/27987762/how-to-set-url-anchor-hash-in-servlets/27988314#27988314
Note that the part of the URL before the anchor is not the same.
In an HTTP servlet, you can achieve this by using the sendRedirect(String) method of the HTTPServletResponse object passed to your service method, for example
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
/* ... */
response.sendRedirect("http://example.com/your/url#hash");
}
However, this, you cannot do: redirect this
http://example.com/some/url
to this
http://example.com/some/url#there
As far as the server is concerned, both are the same address, it cannot distinguish between them. That makes it impossible to check if the address was the first (the one without the URL anchor) and redirect conditionally if it is. Redirecting without checking will, of course, create a redirect loop.
However, depending on what it is exactly you are trying to accomplish, even if you cannot do it in your servlet, you can probably achieve it with client-side scripting (i.e. JavaScript). Have a look at the window.location.hash property.
Once I encountered a similar need.
My problem was:
I had two different forms on the same jsp page (one for registrations and one for logging in). The forms were made visible by hashes in urls, i.e. http://myapp.com/auth#login made login form visible and http://myapp.com/auth#signup made signup form visible.
I needed to show the validation errors to the user by reloading the same page, but couldn't navigate to hashes from my servlet.
Here's how I showed validation errors (jsp):
<form method="post" action="authentication">
<c:forEach items="${errorSignupMessage}" var="message">
<div class="error-message">${message}</div>
</c:forEach>
..................................
</form>
and errorSignupMessage was the attribute I passed in through servlet
request.setAttribute("errorSignupMessage", array);
The solution:
Firstly, I created the hidden field in my form that had to contain the needed attributes:
<input type="text" name="ACTION" class="hidden important" value="signup" data-attr="${errorSignupMessage != null ? true : false}"/>
the important thing to look at is the attribute data-attr. As you can see, I set the boolean value on the attribute depending on actions from servlet, i.e. if the errorSignupMessage is null, than the user interacted with another form and if errorSignupMessage exists and is not null, then the current form is the one the user interacted with.
Then I went to javascript and using window.onload event did the data attribute detection and wrote some logic for changing the location.hash value.
var authForms = document.getElementsByClassName('important');
function changeHash() {
for(var i = 0; i < authForms.length; ++i) {
var form = authForms[i];
if (form.value === 'signup' && form.getAttribute('data-attr') === 'true') {
location.hash = '#signup';
} else {
location.hash = '#login';
}
}
}
window.onload = changeHash;
This is how I solved that. Of course, you'll need to adopt all this for your needs, but I think you still get the general idea.
Hope it was helpful!

How to create a parameter in JSP? [duplicate]

What is the difference between getAttribute() and getParameter() methods within HttpServletRequest class?
getParameter() returns http request parameters. Those passed from the client to the server. For example http://example.com/servlet?parameter=1. Can only return String
getAttribute() is for server-side usage only - you fill the request with attributes that you can use within the same request. For example - you set an attribute in a servlet, and read it from a JSP. Can be used for any object, not just string.
Generally, a parameter is a string value that is most commonly known for being sent from the client to the server (e.g. a form post) and retrieved from the servlet request. The frustrating exception to this is ServletContext initial parameters which are string parameters that are configured in web.xml and exist on the server.
An attribute is a server variable that exists within a specified scope i.e.:
application, available for the life of the entire application
session, available for the life of the session
request, only available for the life of the request
page (JSP only), available for the current JSP page only
request.getParameter()
We use request.getParameter() to extract request parameters (i.e. data sent by posting a html form ). The request.getParameter() always returns String value and the data come from client.
request.getAttribute()
We use request.getAttribute() to get an object added to the request scope on the server side i.e. using request.setAttribute(). You can add any type of object you like here, Strings, Custom objects, in fact any object. You add the attribute to the request and forward the request to another resource, the client does not know about this. So all the code handling this would typically be in JSP/servlets. You can use request.setAttribute() to add extra-information and forward/redirect the current request to another resource.
For example,consider about first.jsp,
//First Page : first.jsp
<%# page import="java.util.*" import="java.io.*"%>
<% request.setAttribute("PAGE", "first.jsp");%>
<jsp:forward page="/second.jsp"/>
and second.jsp:
<%# page import="java.util.*" import="java.io.*"%>
From Which Page : <%=request.getAttribute("PAGE")%><br>
Data From Client : <%=request.getParameter("CLIENT")%>
From your browser, run first.jsp?CLIENT=you and the output on your browser is
From Which Page : *first.jsp*
Data From Client : you
The basic difference between getAttribute() and getParameter() is that the first method extracts a (serialized) Java object and the other provides a String value. For both cases a name is given so that its value (be it string or a java bean) can be looked up and extracted.
It is crucial to know that attributes are not parameters.
The return type for attributes is an Object, whereas the return type for a parameter is a String. When calling the getAttribute(String name) method, bear in mind that the attributes must be cast.
Additionally, there is no servlet specific attributes, and there are no session parameters.
This post is written with the purpose to connect on #Bozho's response, as additional information that can be useful for other people.
The difference between getAttribute and getParameter is that getParameter will return the value of a parameter that was submitted by an HTML form or that was included in a query string. getAttribute returns an object that you have set in the request, the only way you can use this is in conjunction with a RequestDispatcher. You use a RequestDispatcher to forward a request to another resource (JSP / Servlet). So before you forward the request you can set an attribute which will be available to the next resource.
-getParameter() :
<html>
<body>
<form name="testForm" method="post" action="testJSP.jsp">
<input type="text" name="testParam" value="ClientParam">
<input type="submit">
</form>
</body>
</html>
<html>
<body>
<%
String sValue = request.getParameter("testParam");
%>
<%= sValue %>
</body>
</html>
request.getParameter("testParam") will get the value from the posted form of the input box named "testParam" which is "Client param". It will then print it out, so you should see "Client Param" on the screen. So request.getParameter() will retrieve a value that the client has submitted. You will get the value on the server side.
-getAttribute() :
request.getAttribute(), this is all done server side. YOU add the attribute to the request and YOU submit the request to another resource, the client does not know about this. So all the code handling this would typically be in servlets.getAttribute always return object.
getParameter - Is used for getting the information you need from the Client's HTML page
getAttribute - This is used for getting the parameters set previously in another or the same JSP or Servlet page.
Basically, if you are forwarding or just going from one jsp/servlet to another one, there is no way to have the information you want unless you choose to put them in an Object and use the set-attribute to store in a Session variable.
Using getAttribute, you can retrieve the Session variable.
from http://www.coderanch.com/t/361868/Servlets/java/request-getParameter-request-getAttribute
A "parameter" is a name/value pair sent from the client to the server
- typically, from an HTML form. Parameters can only have String values. Sometimes (e.g. using a GET request) you will see these
encoded directly into the URL (after the ?, each in the form
name=value, and each pair separated by an &). Other times, they are
included in the body of the request, when using methods such as POST.
An "attribute" is a server-local storage mechanism - nothing stored in
scoped attribues is ever transmitted outside the server unless you
explicitly make that happen. Attributes have String names, but store
Object values. Note that attributes are specific to Java (they store
Java Objects), while parameters are platform-independent (they are
only formatted strings composed of generic bytes).
There are four scopes of attributes in total: "page" (for JSPs and tag
files only), "request" (limited to the current client's request,
destroyed after request is completed), "session" (stored in the
client's session, invalidated after the session is terminated),
"application" (exist for all components to access during the entire
deployed lifetime of your application).
The bottom line is: use parameters when obtaining data from the
client, use scoped attributes when storing objects on the server for
use internally by your application only.
Another case when you should use .getParameter() is when forwarding with parameters in jsp:
<jsp:forward page="destination.jsp">
<jsp:param name="userName" value="hamid"/>
</jsp:forward>
In destination.jsp, you can access userName like this:
request.getParameter("userName")
Basic difference between getAttribute() and getParameter() is the return type.
java.lang.Object getAttribute(java.lang.String name)
java.lang.String getParameter(java.lang.String name)

Java servlet sendRequest - getParameter encoding Problem

I'm building a web app for my lesson using java servlets. At some point i want to redirect to a jsp page, sending also some info that want to use there (using the GET method).
In my servlet i have the following code:
String link = new String("index.jsp?name="+metadata.getName()+"&title="+metadata.getTitle());
response.sendRedirect(response.encodeRedirectURL(link));
In the jsp, I get these parameters using
<%
request.getParameter("name");
request.getParameter("title");
%>
Everything works fine, except when the parameters do not contain only latin characters (in my case they can contain greek characters).
For example if name=ΕΡΕΥΝΑΣ i get name=¡¥.
How can i fix this encoding problem (setting it to UTF-8)?
Isn't encodeRedirectURL() doing this job? Should I also use encodeURL() at some point? I tried the last one but problem still existed.
Thanks in advance :)
The HttpServletResponse#encodeRedirectURL() does not URL-encode the URL. It only appends the jsessionid attribute to the URL whenever there's a session and the client has cookies disabled. Admittedly, it's a confusing method name.
You need to encode the request parameters with help of URLEncoder#encode() yourself during composing the URL.
String charset = "UTF-8";
String link = String.format("index.jsp?name=%s&title=%s",
URLEncoder.encode(metadata.getName(), charset),
URLEncoder.encode(metadata.getTitle(), charset));
response.sendRedirect(response.encodeRedirectURL(link));
And create a filter which is mapped on /* and does basically the following in doFilter() method:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
And add the following to top of your JSP:
<%# page pageEncoding="UTF-8" %>
Finally you'll be able to display them as follows:
<p>Name: ${param.name}</p>
<p>Title: ${param.title}</p>
See also:
Unicode - How to get characters right?
Use the java.net.URLEncoder to encode each parameter before adding them to the url. Think about it this way: if your name contained a "&", how would you know that this was not a parameter delimiter?
You should encode every request parameter with URLEncoder.encode() before putting it into the query string .
The encodeRedirectURL method is only used to include the session ID into the URL if necessary (URL rewriting if no cookie support by the browser)
How about the following instead?
Set the name and title as attributes on the request object;
Get a request dispatcher for the JSP from the request object or via the servlet context;
Use the request dispatcher to forward the request to the JSP;
Access these attributes in the request from the JSP.
This saves redirecting the browser from the first servlet to the JSP derived servlet and avoids the whole parameter encoding issue entirely.
Also ensure the JSP page directive sets the content encoding to UTF-8.

Using request.setAttribute in a JSP page

Is it possible to use request.setAttribute on a JSP page and then on HTML Submit get the same request attribute in the Servlet?
No. Unfortunately the Request object is only available until the page finishes loading - once it's complete, you'll lose all values in it unless they've been stored somewhere.
If you want to persist attributes through requests you need to either:
Have a hidden input in your form, such as <input type="hidden" name="myhiddenvalue" value="<%= request.getParameter("value") %>" />. This will then be available in the servlet as a request parameter.
Put it in the session (see request.getSession() - in a JSP this is available as simply session)
I recommend using the Session as it's easier to manage.
The reply by Phil Sacre was correct however the session shouldn't be used just for the hell of it. You should only use this for values which really need to live for the lifetime of the session, such as a user login. It's common to see people overuse the session and run into more issues, especially when dealing with a collection or when users return to a page they previously visited only to find they have values still remaining from a previous visit. A smart program minimizes the scope of variables as much as possible, a bad one uses session too much.
You can do it using pageContext attributes, though:
In the JSP:
<form action="Enter.do">
<button type="SUBMIT" id="btnSubmit" name="btnSubmit">SUBMIT</button>
</form>
<% String s="opportunity";
pageContext.setAttribute("opp", s, PageContext.APPLICATION_SCOPE); %>
In the Servlet (linked to the "Enter.do" url-pattern):
String s=(String) request.getServletContext().getAttribute("opp");
There are other scopes besides APPLICATION_SCOPE like SESSION_SCOPE. APPLICATION_SCOPE is used for ServletContext attributes.
If you want your requests to persists try this:
example: on your JSP or servlet page
request.getSession().setAttribute("SUBFAMILY", subFam);
and on any receiving page use the below lines to retrieve your session and data:
SubFamily subFam = (SubFamily)request.getSession().getAttribute("SUBFAMILY");
Try
request.getSession().setAttribute("SUBFAMILY", subFam);
request.getSession().getAttribute("SUBFAMILY");
Correct me if wrong...I think request does persist between consecutive pages..
Think you traverse from page 1--> page 2-->page 3.
You have some value set in the request object using setAttribute from page 1, which you retrieve in page 2 using getAttribute,then if you try setting something again in same request object to retrieve it in page 3 then it fails giving you null value as "the request that created the JSP, and the request that gets generated when the JSP is submitted are completely different requests and any attributes placed on the first one will not be available on the second".
I mean something like this in page 2 fails:
Where as the same thing has worked in case of page 1 like:
So I think I would need to proceed with either of the two options suggested by Phill.
i think phil is right request option is available till the page load. so if we want to sent value to another page we want to set the in the hidden tag or in side the session if you just need the value only on another page and not more than that then hidden tags are best option if you need that value on more than one page at that time session is the better option than hidden tags.

Categories

Resources