I’ve spent the last hour creating a very simple Tapestry page but one that i think is very useful. It’s a page that shows application and session information. Here’s an example of what the page can show:
As you can see it’s got a very simple design but it gets the job done.
The information you’ll probably find most useful is the session size. With this page you can easily check if you’re putting too much information in the http session.
I’m going to create an issue to see if the Tapestry devs want to include this page on the framework. In the meantime here’s the code for the page so you can add it to your application.
The page class
public class ApplicationStatus {
@Inject
@Property
private ApplicationGlobals applicationGlobals;
@Inject
@Property
private RequestGlobals requestGlobals;
@Property
private List
@Property
private int totalSessionSize;
@Property
private SessionAttributeInfo currentSessionAttribute;
void setupRender() throws IOException {
sessionAttributes = new ArrayList
if (getSession() != null) {
Enumeration attributeNames = getSession().getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement().toString();
SessionAttributeInfo sessionAttributeInfo = new SessionAttributeInfo(attributeName);
sessionAttributeInfo.setType(getSession().getAttribute(attributeName).getClass().getName());
sessionAttributeInfo.setSerializable(true);
ByteArrayOutputStream baos;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(getSession().getAttribute(attributeName));
sessionAttributeInfo.setSize(baos.size());
totalSessionSize += baos.size();
} catch (NotSerializableException ex) {
sessionAttributeInfo.setSerializable(true);
} finally {
if (oos != null) {
oos.close();
}
}
sessionAttributes.add(sessionAttributeInfo);
}
}
}
@Cached
public HttpSession getSession() {
return requestGlobals.getHTTPServletRequest().getSession(false);
}
public Date getDate(long time) {
return new Date(time);
}
public String formatSize(int size) {
return StorageUnit.of(size).format(size);
}
public enum StorageUnit {
BYTE("bytes", 1L),
KILOBYTE("KB", 1L << 10),
MEGABYTE("MB", 1L << 20),
GIGABYTE("GB", 1L << 30),
TERABYTE("TB", 1L << 40),
PETABYTE("PB", 1L << 50),
EXABYTE("EB", 1L << 60);
public static final StorageUnit BASE = BYTE;
private final String symbol;
private final long divider; // divider of BASE unit
StorageUnit(String name, long divider) {
this.symbol = name;
this.divider = divider;
}
public static StorageUnit of(final long number) {
final long n = number > 0 ? -number : number;
if (n > -(1L << 10)) {
return BYTE;
} else if (n > -(1L << 20)) {
return KILOBYTE;
} else if (n > -(1L << 30)) {
return MEGABYTE;
} else if (n > -(1L << 40)) {
return GIGABYTE;
} else if (n > -(1L << 50)) {
return TERABYTE;
} else if (n > -(1L << 60)) {
return PETABYTE;
} else { // n >= Long.MIN_VALUE
return EXABYTE;
}
}>>>>>>
public String format(long number) {
return nf.format((double) number / divider) + " " + symbol;
}
private static java.text.NumberFormat nf
= java.text.NumberFormat.getInstance();
static {
nf.setGroupingUsed(false);
nf.setMinimumFractionDigits(0);
nf.setMaximumFractionDigits(1);
}
}
public static class SessionAttributeInfo {
private String name;
private String type;
private boolean serializable;
private Integer size;
public SessionAttributeInfo(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSerializable() {
return serializable;
}
public void setSerializable(boolean serializable) {
this.serializable = serializable;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
}
The Page Template
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Context Path: ${requestGlobals.request.contextPath}
Servlet Version: ${applicationGlobals.servletContext.majorVersion}.${applicationGlobals.servletContext.minorVersion}
Server Info: ${applicationGlobals.servletContext.serverInfo}
Id: ${session.id}
Creation Date: ${getDate(session.creationTime)}
Last Accessed Date: ${getDate(session.lastAccessedTime)}
Estimated Size: ${formatSize(totalSessionSize)}
@Inject
@Property
private ApplicationGlobals applicationGlobals;
@Inject
@Property
private RequestGlobals requestGlobals;
@Property
private List
@Property
private int totalSessionSize;
@Property
private SessionAttributeInfo currentSessionAttribute;
void setupRender() throws IOException {
sessionAttributes = new ArrayList
if (getSession() != null) {
Enumeration attributeNames = getSession().getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement().toString();
SessionAttributeInfo sessionAttributeInfo = new SessionAttributeInfo(attributeName);
sessionAttributeInfo.setType(getSession().getAttribute(attributeName).getClass().getName());
sessionAttributeInfo.setSerializable(true);
ByteArrayOutputStream baos;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(getSession().getAttribute(attributeName));
sessionAttributeInfo.setSize(baos.size());
totalSessionSize += baos.size();
} catch (NotSerializableException ex) {
sessionAttributeInfo.setSerializable(true);
} finally {
if (oos != null) {
oos.close();
}
}
sessionAttributes.add(sessionAttributeInfo);
}
}
}
@Cached
public HttpSession getSession() {
return requestGlobals.getHTTPServletRequest().getSession(false);
}
public Date getDate(long time) {
return new Date(time);
}
public String formatSize(int size) {
return StorageUnit.of(size).format(size);
}
public enum StorageUnit {
BYTE(”bytes”, 1L),
KILOBYTE(”KB”, 1L << 10),
MEGABYTE(”MB”, 1L << 20),
GIGABYTE(”GB”, 1L << 30),
TERABYTE(”TB”, 1L << 40),
PETABYTE(”PB”, 1L << 50),
EXABYTE(”EB”, 1L << 60);
public static final StorageUnit BASE = BYTE;
private final String symbol;
private final long divider; // divider of BASE unit
StorageUnit(String name, long divider) {
this.symbol = name;
this.divider = divider;
}
public static StorageUnit of(final long number) {
final long n = number > 0 ? -number : number;
if (n > -(1L << 10)) {
return BYTE;
} else if (n > -(1L << 20)) {
return KILOBYTE;
} else if (n > -(1L << 30)) {
return MEGABYTE;
} else if (n > -(1L << 40)) {
return GIGABYTE;
} else if (n > -(1L << 50)) {
return TERABYTE;
} else if (n > -(1L << 60)) {
return PETABYTE;
} else { // n >= Long.MIN_VALUE
return EXABYTE;
}
}>>>>>>
public String format(long number) {
return nf.format((double) number / divider) + ” ” + symbol;
}
private static java.text.NumberFormat nf
= java.text.NumberFormat.getInstance();
static {
nf.setGroupingUsed(false);
nf.setMinimumFractionDigits(0);
nf.setMaximumFractionDigits(1);
}
}
public static class SessionAttributeInfo {
private String name;
private String type;
private boolean serializable;
private Integer size;
public SessionAttributeInfo(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isSerializable() {
return serializable;
}
public void setSerializable(boolean serializable) {
this.serializable = serializable;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
}