<title>Servlets and JSP</title>

<summarylist/>

<section title="How do I enable session url rewriting?">

<p/>You can disable cookies in the resin.conf with a configuration like

<example>
&lt;http-server&gt;

  &lt;session-config
   enable-cookies='false'
   enable-url-rewriting='true'/&gt;

&lt;/http-server&gt;
</example>

</section>

<section title="How do I keep the generated .java files?">

<p/>The generated .java files are put in <var/&lt;java work-dir>/>.  By
default, that's <var//tmp/caucho/> on Unix and <var/\temp\caucho/> on
Windows.

</section>

<section title="Class work.test.MyBean not found">

Your jsp file must import the proper packages so Java can find the
bean.  Also, the bean should typically be in <var/resin/doc/WEB-INF/classes/>.

<example>
&lt;%@ page import='test.*' %>
&lt;%= MyBean.printData() %>
</example>

<p/>Also, if your bean has no package, you need to import the bean by name:

<example>
&lt;%@ page import='MyBean' %>
&lt;%= MyBean.printData() %>
</example>

</section>

<section title="My character encoding is messed up">

Resin has an optimization, <var/static-encoding/>, which assumes that
your page is written in the same encoding as you're printing.  That usually
works, but some people write a page in one encoding, like <var/Shift-JIS/>
and print it in <var/UTF-8/>.  To make that work, you need to disable
<var/static-encoding/>.

<example>
&lt;jsp static-encoding='false'/>
</example>

Here's an example page that would need to disable static-encoding:

<example>
&lt;%@ page contentType='text/html; charset=Shift-JIS' %>
&lt;% response.setContentType("text/html; charset=UTF-8") %>
...
</example>

</section>

<section title="Form character encoding doesn't work">

A POST request with application/x-www-form-urlencoded doesn't contain any
information about the character request.  So Resin needs to use a set of
heuristics to decode the form.  Here's the order:

<ol>
<li>request.getAttribute("caucho.form.character.encoding")
<li>The response.setContentType() encoding of the page.
<li>The <var/character-encoding/> tag in the resin.conf.
</ol>

Resin uses the default character encoding of your JVM to read form data.  To
set the encoding to another charset, you'll need to change the resin.conf as
follows:

<example>
&lt;http-server character-encoding='Shift_JIS'>
  ...
&lt;/http-server>
</example>

</section>

<section title="Error 405 resource not found">

Usually, this is a servlet extending HttpServlet and implementing
doGet but not doPost.  If you send a POST request, like a form, to a
servlet that only implements doGet, you will get 405 resource not found.

</section>

<section title="How do I print an exception stack trace to the JSP out?">

Mattias Nilsson writes:

<p>Here's the code I use for dumping exceptions on JSP pages

<example>
catch(Exception e) {
  ByteArrayOutputStream bout = new ByteArrayOutputStream();
  e.printStackTrace(new PrintStream(bout)); 
  out.println(bout.toString());
}
</example>   

also very useful to include in error emails etc.

</section>

<section title="How do I delete cookies?">

Normally, you can just grab the cookie from <var/request.getCookies()/>,
call <var/cookie.setMaxAge(0)/>, and add the cookie to the Response.

<p/>One thing you may need to watch out for is that the <var/Path/> and
<var/Domain/> of the deleting cookie must match the browser's cookie.  By
default, Resin does not set <var/Path=//>.

<p/>If you set a cookie header explicitly, you may want to call <var/setPath("/")/>.

<example>
response.addHeader("Set-Cookie: foo=bar");
</example>

To delete this cookie, you must call:

<example>
Cookie cookie = new Cookie("foo", "bar");
cookie.setPath(null);
response.addCookie(cookie);
</example>

</section>

<section title='What is a web-app?'>

The vast majority of sites can completely ignore web-apps.  If you're
starting with Resin, use the default web-app and don't worry about it.

<p/>You'll only want to use web-apps when you want separate projects using
the same web server.  For example, on an ISP site, each user might get her
own web-app.  She can treat the web-app as if she had control over
the whole web server starting at a URL prefix like <var/~karen/>.

<p/>A web-app is a generalization of a virtual host.  With virtual
hosts, each host pretends that it controls its own server when it
really is sharing the server with other virtual hosts.  A web-app
extends this by creating virtual applications for a URL prefix.

<p/>Each web-app gets its own sessions, servlets, beans and static
pages.

</section>

<section title="Why don't my URLs work in my web-app?">

Remember, the browser doesn't know about your web-apps.  It treats the
web server as a single URL-space.  This may cause you troubles if you
use a standard directory structure like putting images in '/images/*'.

<p/>To see this problem, suppose you have a web-app called
'/myproject'.  Suppose you have a JSP page in the web-app called
<var/foo/bar.jsp/>.  The full URL will be
<var//myproject/foo/bar.jsp/>.  Your image reference should look like
one of the following:

<example>
&lt;img src='../images/image1.gif'/><br>
&lt;img src='&lt;%= request.getContextPath() %>/images/image1.gif'/>
</example>

Using <var//images/image1.gif/> will fail because the browser will
look for <var/http://myhost.com/images/image1.gif/> when you really
want <var/http://myhost.com/myproject/images/image1.gif/>.

</section>

<section title="How do I stop the browser from caching my page?">

Unfortunately, all the browsers work differently.  The following seems to
be a consensus on the headers to set:

<example>
response.setHeader("Cache-Control", "no-cache, post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
</example>

</section>

<section title="How do I precompile *.jsp pages?">

You can run Resin on a single page from the shell:

<example>
unix> httpd.sh -e /test/myfile.jsp
</example>

That will compile the JSP.  When you next start Resin, the JSP file will
already be available.

<p/>You can also use a link checker spider to traverse your website to
hit all the pages you want to precompile.

</section>

<section title="VerifyError when loading JSP files">

The JVM has a number of limits on a method's code size.
Most compilers won't tell you that you've exceeded the limit, so you'll
see the error when Resin tries to load the compiled code.  This can be
especially troublesome if you use tag libraries heavily, because each
tag generates a fairly large amount of code.

<p/>The only real solution is to break your pages into subpages using
jsp:include.  That may actually turn out to be an advantage because you can
then use Resin's caching to improve the performance of those subpages.

</section>

<section title="How can I open a data file?">

You'll need to translate the URL to a real path using
<var/getRealPath/>.  Resin's current directory is <var/RESIN_HOME/>
which is normally not where you'll be storing data files.  You can
look up a real path based on the <var/web-app/> using
<var/ServletContext.getRealPath()/> or relative to the current URL
using <var/ServletRequest.getRealPath()/>.

<example>
ServletContext app = getServletContext();
String path = app.getRealPath("/WEB-INF/mydata.csv");
InputStream is = new FileInputStream(path);
...
</example>

</section>

<section title="Character encoding problems on Solaris POST">

Nicolas Lehuen writes:

<p/>I'm running Resin 1.2.s000920 either on the Windows 2000 (JDK 1.3.0_01) or
Solaris platform (JDK 1.2.2 + Hotspot 1.0.1). When POSTing forms with
accents from IE 5.5 on Win2000 to the server running on Win2000,
everything
is allright. If the server runs on Solaris, I get '?' instead of the
accentuated characters.
I have read the FAQ about this, and tried to set the 'character-encoding'
attribute of the http-server tag to 'ISO_8859_1' or '646' (which seems to
be
the default character encoding on the Solaris platform, as reported by the
'file.encoding' system property). I also tried setting the
caucho.form.character.encoding attribute of the HttpRequest to ISO_8859_1.
Nothing changes, on Solaris I always get '?' instead of accentuated
characters.

<p/>Two questions, there :
<ol>
<li>what am I doing wrong ?
<li>I have to set a particular character encoding for the request to be
parsed correctly. Given that I build a multi-device, multi-language
platform, is there any guidelines to guess the character encoding used by
the POSTing browser ? Why isn't there a "; charset=xxxx" suffix to the
"Content-Type: application/x-www-form-urlencoded" ?
</ol>

<p/>Rogério Saran writes:

<p/>Nicolas, Solaris JVMs follows the default system locale for character
output. A bug on some Solaris installers can damage the system default
locale and leave it with invalid settings.

<p/>Check your settings with the "locale" console comand. It will probably
not look "good", with lots of "C"s replacing valid settings. Just change
/etc/default/init and make it look like:

<pre>
TZ=Brazil/East
CMASK=022
LC_COLLATE=en_US.ISO8859-1
LC_CTYPE=en_US.ISO8859-1
LC_MESSAGES=C
LC_MONETARY=en_US.ISO8859-1
LC_NUMERIC=en_US.ISO8859-1
LC_TIME=en_US.ISO8859-1
</pre>

<p/>You will nee to reboot the machine to make these settings valid for all
running processes. If you don't want to restart the system you may also
add the lines above to your Resin startup script - just set these
environment variables before calling RESIN_HOME/bin/httpd.sh.

<p/>Nicolas Leheun writes:

<p/>Thanks to Rogério Saran, the solution of correctly defining the Solaris
5.7 locale thanks to the /etc/default/init file works fine. I just had to
find out the fact that 'su -' was corrupting the locale configuration,
whereas a simple 'su' does not. The '-' is meant to pass along the current
user environment to the super-user, but it is not the case for the locale,
at least in my version of Solaris 5.7 :(

<p/>Thanks also to Eric Arrive (a former colleague !) for his very interesting
<a href="http://w6.metronet.com/~wjm/tomcat/FromFeb11/msg01556.html">line</a>, which I'll save immediatly as an excuse for not having a better solution than
changing the default locale of the VM ! We're serving i-Mode also, don't
ask me how I'll handle japanese form postings for the moment...

</section>

<section title="How do I logout with the Authenticator?">

The servlet API doesn't have a good way of handling logout.  (The
authentication in the spec is really only partially thought-out.)

<p/>You can write a logout method that looks like:

<example>
public static final String LOGIN_NAME =
  "com.caucho.servlet.login.name";
/**
 * Logs the user out from the session.
 *
 * @param request the servlet request
 */
public void logout(HttpServletRequest request)
{
  HttpSession session = request.getSession(false);
  if (session != null)
    session.removeValue(LOGIN_NAME);
}
</example>

<p/>Or you could invalidate the session.  Invalidating the session will
remove all information, including login information.

<p/>Until we come up with a way to get the authenticator object from a servlet,
there's really no other way to deal with this.

</section>
