Page caching problem - spring

I use JSP (Spring MVC) for showing information to remote user. I have some problems with caching of page. It looks like this:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>My Title</title>
</head>
<body>
<jsp:include page="menu.jsp" flush="true" />
<form method="post">
Write here
<input type="text" name="inputTxt" value="${txt}" />
<input type="submit" value="OK" />
</form>
<table border="1">
...
</table>
</body>
</html>
Page should show a table of items. When user press OK button, server add information to the database and add a row to the table. All works fine. But tables shows an information depends on the logged user. So, when I login for the first time, my app works great (shows me the data, corresponding to the current user). But when I logout from current user and login from new, this page still show data for firs user. If I press F5, table update it's data and shows correct information, which corresponds to the current user. I think problems with caching.
How to avoid this problem? Any ideas?

The page is indeed likely cached by the browser. You can verify this in Firefox with Firebug. Generally, you would like to disable client side caching of dynamic content. You can achieve this by creating a Filter which is mapped on an url-pattern of *.jsp and does basically the following job in the doFilter() method.
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
Those response headers will instruct the client (webbrowser) to not cache the response. Don't forget to clean the browser cache before testing.
In Spring MVC, you can create an interceptor like so:
public class DisableBrowserCachingInterceptor extends HandlerInterceptorAdapter {
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
response.setHeader("Pragma", "no-cache"); // HTTP 1.0
response.setDateHeader("Expires", 0); // Proxies
}
}

Related

"Server error" while hitting a URL from controller in SAP Hybris

I am trying to practice SAP Hybris basic flow and while hitting the URL from the controller I am getting a "server error" as the response as shown below.
The controller looks something like this:
#Controller
public class NewCustomerController {
#RequestMapping(value = "/custid", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getCustomerNameFromCustId(#RequestBody final Model model){
final List<NewCustomerData> nameList = newCustomerFacade.getCustomerNamefromID();
model.addAttribute("nameList",nameList);
return ControllerConstants.Views.Pages.NewCustomer.CustId;
}
}
The JSP page "custid.jsp" looks something like this:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="" tagdir="" %>
<html>
<head>
<title>Customer ID detail</title>
</head>
<body>
<h1>This page displays the name of the customer based on customer ID</h1>
<h3>The name of the customer is ${nameList}.<h3>
</body>
</html>
In the dao layer, when I evaluate the call to execute the query, I get this error:
Can anyone help me please what am I doing wrong? I am stuck on this since 2 days now.

Spring Model Attribute overriding the Session Attribute with same name

I am very new to Spring world and trying a few things related to Spring MVC and session handling.
my question is that if we have Model Attribute and session attribute of same name then does the Model Attribute overrides the value of session attribute ?
In code snippet below (apologies for poor formatting, I am new here) I am adding an attribute names sessionAttribute into Model and Session. While accessing the same attribute in JSP I am getting value of Model Attribute ([name] as Model Attribute ).
#RequestMapping(value="/hello", method=RequestMethod.GET)
public String hello(#RequestParam(value="username", required=false,defaultValue="World") String name, Model model,HttpServletRequest req) {
model.addAttribute("sessionAttribute", name+" as Model Attribute");
System.out.println("In controller");
HttpSession hs=req.getSession();
hs.setAttribute("sessionAttribute","overridden Session attribute"); //prints"overridden Session attribute"
System.out.println(hs.getAttribute("sessionAttribute"));
return "someViewName";
}
Below is the View (someViewName) and it is printing the value of sessionAttribute as Model attribute
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring4 MVC -HelloWorld</title>
</head>
<body>
<% HttpSession hs=request.getSession();
String sesstionAttr=(String)session.getAttribute("sessionAttribute");
out.println(sesstionAttr); //printin [name] as Model Attribute
%>
</body>
</html>
my question is that if we have Model Attribute and session attribute
of same name then does the Model Attribute overrides the value of
session attribute ?
In general, model and session are different things, therefore model attributes and session attributes are different. Model attributes are referring to the model properties (which you have in your view), and session attributes are stored in http session, so that if you add one attribute in session in one controller and then change a view, you can still access added attribute in another one.
So if you are inside of your controller method, adding the session attribute into session will not override the value in model attribute.
However, this may happen in one case - if you are using #SessionAttributes provided by Spring exactly for this reason.
When using #SessionAttributes after your method execution will be finished, Spring will load all attributes from your model, and add them into the session (so that if you have the same name it will be overridden). And next time you try to access the attribute from the session - you will see overridden value from model.
For me it looks like this is happening in your case. However I do not how you have configured your controller, so check if you have specified
SessionAttributes or not.

Java - modelandview in modelandview

How can I addObject to modelandview with modelandview parameter? I mean something like that:
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
ModelAndView m = new ModelAndView();
m.addObject("test", t, '1');
mav.addObject("site", m);
I mean I have a index file witch I deal like a template and I want to parse it to other file (template)
My second question:
Is this good solution? If not, please tell me what is preffered:)
Sorry, I'm new to Java EE and Spring
edit: source code
ModelAndView is just a container used by Spring's MVC request handling. Every object you add to ModelAndView will be added as request attribute (request#setAttribute) and then available within your JSP.
Nesting ModelAndView does not make any sense. You can just forward the request from your JSP file and all the model attributes will be still set on the request and available.
Regarding your approach:
I would say that having template JSP (such as your index) can be used. I personally prefer having TAG file with layout and then JSP files being enclosed within this layout.
<%# tag language="java" description="Content border for layout decoration." trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html lang="cs">
<head profile="http://www.w3.org/2005/10/profile">
<meta charset="utf-8" />
</head>
<body>
<div class="pageContent">
<jsp:doBody />
</div>
</body>
</html>
-
<%# include file="/WEB-INF/taglib.jspf"%>
<layout:admin>
THIS IS MY CONTENT
</layout:admin>
Alternatively you can use templating engine such as Apache Tiles.

request.getParameter() returns null

Got a homework assignment that is giving me problems.... Its modifying a JSF project with two pages and a bean to fit MVC2 by adding two more pages and a controller servlet and another bean for the two additional pages. the new main page forwards to either the second new page or the old first page. My issue is response.getParameter() always results in null.
<%#page session="false" import="java.util.Iterator"%>
<%#taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%#taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<jsp:useBean id="status" scope="request" class="JSFRegistration.Status" />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JSP Page</title>
</head>
<body>
<% if (status!=null && !status.isSuccessful()){%>
<font color="red">Processing errors:
<ul><%Iterator errors=status.getExceptions();
while (errors.hasNext()){
Exception e = (Exception) errors.next();%>
<li><%= e.getMessage()%><%}%></ul></font><%}%>
<form action="LoginServlet" method="POST">
<% String username = request.getParameter("username");
if (username==null) username="";%>
<input type="text" name="usernameTF" value="<%=username%>" />
<% String password = request.getParameter("password");
if (password==null) password="";%>
<input type="password" name="passwordTF" value="<%=password%>" />
<input type="submit" value="Login" />
</form>
</body>
</html>
this is basically a direct copy from our book but the fields I need for the new main page. Same for the controller servlet, a direct copy except only contains the fields I need.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher view = null;
Status status = new Status();
request.setAttribute("status", status);
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username==null || username.length()==0)
status.addException(new Exception("Please enter username"));
if (password==null)
status.addException(new Exception("Please enter password"));
if (!status.isSuccessful()){
view = request.getRequestDispatcher("Login.jsp");
//view.forward(request, response);
}
else
try{
request.setAttribute("username", username);
request.setAttribute("password", password);
view = request.getRequestDispatcher("Registration.jsp");
} catch (Exception e) {
status.addException(new Exception("Error"));
view = request.getRequestDispatcher("Login.jsp");
}
view.forward(request, response);
}
and the Status class, again a direct copy from the book.
public class Status {
private ArrayList exceptions;
public Status(){
exceptions = new ArrayList();
}
public void addException(Exception exception) {
exceptions.add(exception);
}
public boolean isSuccessful(){
return (exceptions.isEmpty());
}
public Iterator getExceptions(){
return exceptions.iterator();
}
regardless of what is typed into the two boxes, stepping through a debug shows the values not getting passed to the parameters. I get the created exceptions printed above the screen for both fields if both have text, if only one has text and when both are empty.
Your request parameter names do not match the input field names. You've assigned the input fields a name of usernameTF and passwordTF. They are then available by exactly those names as request parameter, but you're attempting to get them using the names username and password. So you need either to fix the input field names, or the request parameter names so that they match each other.
By the way, why falling back from a modern MVC framework like JSF to awkward 90's style JSP with mingled business code? Is that really what the homework assignment is asking you? Also the HTML <font> element is deprecated since 1998. Where did you learn about it? Is the quality of the course really good?

Can't create a PDF with iText and JSF

I want to create a pdf using iText in my JSF + Spring web app.
When I click on a button the pdf should be generated. The method that is fired:
public void createPDF() {
log.debug("entered createPDF");
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "inline=filename=file.pdf");
try {
// Get the text that will be added to the PDF
String text = "test";
// step 1
Document document = new Document();
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
document.add(new Paragraph(text));
// step 5
document.close();
// setting some response headers
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
// setting the content type
response.setContentType("application/pdf");
// the contentlength
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
log.debug("flushed and closed the outputstream");
}
catch(DocumentException e) {
log.error("error: "+e);
}
catch (IOException e) {
log.error("error: "+e);
}
catch (Exception ex) {
log.debug("error: " + ex.getMessage());
}
context.responseComplete();
log.debug("context.responseComplete()");
}
this is the page with the button:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.org/seam/faces"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:c="http://java.sun.com/jsp/jstl/core"
template="/pages/layout/layout.xhtml">
<ui:define name="content">
<h:form>
<rich:panel style="width: 785px; height: 530px; ">
<a4j:commandButton value="Afdrukken" execute="#form"
action="#{huishoudinkomenAction.print}" style="float:right;" />
</rich:panel>
</h:form>
</ui:define>
I see the debug messages in the log but nothing happens to the web app. I don't see a pdf.
What am I doing wrong?
Regards,
Derk
EDIT:
When I changed the <a4j:commandButton /> to a <h:commandButton /> it worked.
I've never used RichFaces, but with Primefaces controls, you can set the attribute ajax="false".
<p:commandButton id="someid" value="Text for user" action="someConfiguredAction" ajax="false"/>
or
<h:commandButton id="someid" value="Text for user" action="someConfiguredAction"/>
When you use <a4j:commandButton> a new XmlHttpRequest will be created on your browser, and your serverside method will be called via JS. The output PDF will be written into the output stream, but the actual result will be read out of XmlHttpRequest, and interpreted by jsf.ajax.response() javascript function.
Since JSF ajax responses are always XML with a root of <partial-response>, you're basically sending junk back to the JSF ajax handler. (PDF != XML with <partial-response> root). Obviously this fails parsing so it appears that "nothing happens".
So you must use the <h:commandButton/> to do a real request. You need also to do:
response.setHeader("Content-disposition", "attachment; filename=mycool.pdf");
serverside in order to inform the browser that it receives a new file, and should download it, and not display it instead of the page.
This will have the end behavior of an "ajax" call, where you do a call, you receive the response (and save it), but your page content stays there.
You can't download files with ajax. Ajax is fired and handled by JavaScript code. However, JavaScript has for obvious security reasons no way to force a Save As dialogue with arbitrary content in a JavaScript variable (such as the response of an ajax request).
Make sure that the download button fires a synchronous (non-ajax) request. Use a normal command button or turn off ajax in the ajax command button.

Resources