How can I prevent IE from caching responses?

I’m using the <ora:noCache> action described in Chapter 12 in your book, but Internet Explorer caches the responses anyway.What can I do to prevent caching?
Answer:
Unfortunately, IE is infamous for ignoring cache headers and it seems like different versions of IE have different bugs in this area. Using the <ora:noCache/> custom action from Chapter 12 in the main JSP file shouldwork, but I can’t guarantee that since some browsers are buggy. One thing you can try is to use the value 0 or -1 instead of 1 for Expires. Before changing the code for <ora:noCache>, you can test with a scriptlet:

<%
  response.addHeader("Pragma", "No-cache");
  response.addHeader("Cache-Control", "no-cache");
  response.addDateHeader("Expires", -1");
%>

Another trick is to use the corresponding meta tags both at the top and at the bottomof the JSP page:

<HTML>
  <HEAD>
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
  <BODY>
    The content ...
  </BODY>
  <HEAD>
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Expires" CONTENT="-1">
  </HEAD>
</HTML>

This is, of course, invalid HTML but it’s a solution MS provides for this bug, see http://support.microsoft.com/support/kb/articles/Q222/0/64.ASP

On the server side, to make sure that changes to the JSP file take effect immediately, you should always use the include action, i.e. <jsp:include>. This has nothing to do with browser caching, though. See the book and my Top Ten Tips article for more on the different ways to include page fragments and what happens when the included fragment is changed.

Finally, if everything else fails, you can make sure each request is done with a unique URL by adding a dummy query string parameter, e.g. a timestamp like “?ts=123456″. A browser can not use a cached result if the query string is different from the one for the cached result.

Why doesn’t an empty field reset my bean property?

As you explained in When can a parameter value be null?, an empty text form field value is typically sent to a JSP (or servlet) page as an empty string parameter value.But a String property in my bean corresponding to a text field does not get set to an empty string when I use the setProperty action. What’s going on?
Answer:
I describe this in Chapter 15 in the book, in the section Unexpected <jsp:setProperty> Behavior.To match the behavior for properties corresponding to checkboxes, radio buttons and selection lists, the JSP specification says that if a parameter value is an empty string, the corresponding property setter method should notbe called. So when you use

<jsp:setProperty name="foo" property="*" />

for a bean with properties corresponding to various types of form elements, an empty text field has the same effect as a checkbox that is not checked; the property is not set at all.

If you use a bean to capture form input and you want to reset a property when the user clears the corresponding form field, you can use this work-around. First create a method in the bean that resets all properties:

public void setReset(String ignored) {
  myFirstProperty = null;
  mySecondProperty = null;
  ...
}

Now you can invoke this method before you set the properties based on the current form field values in your JSP page:

<jsp:setProperty name="foo" property="reset" value="dummy"/>
<jsp:setProperty name="foo" property="*" />

When can a parameter value be null?

I’ve noticed that request.getParameter() always return a string for the parameter that corresponds to a text field in my form, even when the field is empty. To find out if the field is empty, I need to use code like this:

if (request.getParameter("foo").length() == 0) {
  ...
}

But in your book, you have examples where you test if the parameter value is null instead.

When is the value null and when is it an empty string?

Answer:
Most (all?) browers send empty form text fields to the server as an HTTP request parameter with an empty value. Hence, the value for a text field will rarely be null. Typically it’s an empty string. But it never hurts to test for both null and empty string to be on the safe side:

String foo = request.getParameter("foo");
if (foo == null || foo.trim().length() == 0) {
  ...
}

For checkboxes, radio buttons and select lists, on the other hand, the browser only sends a parameter if the item is selected. For these types of form elements, you must always be prepared to handle a null value.

How to pass request parameters to frame pages?

I have a servlet (or JSP) that sets a request attribute and then forwards to a JSP page. This JSP page contains a frame set, where each frame contains another JSP page. When I try to access the request attribute (as a request scope bean) in the JSP pages that represent the frames, it is not available anymore.

I know I could use session scope beans instead, but since the attribute values are only needed while setting up the frame pages, I want to avoid that. How can it be done?

Answer:
The reason you can’t use request attributes to transfer info to the JSPs loaded in separate frames is that request attributes are only available while you process the same request; the frame JSPs are retrieved with separate requests from the one that invokes the servlet.Here the servlet sets the attribute and forwards to the first JSP page. This means this JSP page processes the same request as the servlet, and can access the attribute. But this JSP page just sends back a response that contains the frame set. The browser then makes new requests for the JSP pages that represent each frame. A new request means that the original request attribute is lost.What you can do is let the first JSP generate the frame set so that each frame src attribute include a request parameter with a value created from the request attribute. The parameter is then sent by the browser with the request for each frame JSP page:

<frameset rows="65%,35%">
  <frame src="a.jsp?foo= name="a">
  <frame src="b.jsp?foo= name="b">
  <noframes>
    <body>
      Viewing this page requires a browser capable of displaying frames.
    </body>
  </noframes>
</frameset>

Note that this only works for request attributes of type String (or attributes that can be converted to a meaningful String).

The frame JSP pages can access the parameter value using a scriptlet, useBean/setProperty or a custom action:

<% String foo = request.getParameter("foo"); %>

<jsp:useBean id="pars" class="com.mycomp.MyBean" />
<jsp:setProperty name="pars" property="*" />

<mylib:doSomething param="foo" />

That is, in the same way as a JSP page gets access to any parameter value.

Can I communicate between JavaScript code and JSP?

I need to use JavaScript code to perform some user interaction based on data that is stored in a database. How can I get this data to the JavaScript code using JSP? And how can I communicate back from JavaScript code to JSP.
Answer:
The book contains a brief example of how you can generate JavaScript code from a JSP page. It does not show how to pass variables between the two environments, but it does describe in some detail the main concepts you need to understand: that JSP code executes on the server and JavaScript code executes in the browser.Given that, the only way to pass variable values from JSP code to JavaScript code is to generate JavaScript variable assignments dynamically in the JSP page, e.g.

<script language="JavaScript">
  // JavaScript code
  var choices = new Array();
  <%
    // Java code in a JSP scriptlet that assigns the
    // JavaScript array elements to values of a Java
    // array created earlier in the JSP page.
    for (int i = 0; i < aJavaArray.length; i++) {
  %>
      choices[<%= i %>] = "<%= aJavaArray[i] %>";
  <% } %>
  // More JavaScript code
  ...
</script>

In the other direction, the only way is to use JavaScript to set HTTP parameter values that get sent with a request for a JSP page, e.g. setting the value of a hidden field.