HttpSession
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.
The servlet container uses this interface to create a session between an HTTP client and an HTTP server. The session persists for a specified time period, across more than one connection or page request from the user. A session usually corresponds to one user, who may visit a site many times. The server can maintain a session in many ways such as using cookies or rewriting URLs.
This interface allows servlets to
* View and manipulate information about a session, such as the session identifier, creation time, and last accessed time
* Bind objects to sessions, allowing user information to persist across multiple user connections
When an application stores an object in or removes an object from a session, the session checks whether the object implements HttpSessionBindingListener. If it does, the servlet notifies the object that it has been bound to or unbound from the session. Notifications are sent after the binding methods complete. For session that are invalidated or expire, notifications are sent after the session has been invalidatd or expired.
When container migrates a session between VMs in a distributed container setting, all session atributes implementing the HttpSessionActivationListener interface are notified.
A servlet should be able to handle cases in which the client does not choose to join a session, such as when cookies are intentionally turned off. Until the client joins the session, isNew returns true. If the client chooses not to join the session, getSession will return a different session on each request, and isNew will always return true.
Session information is scoped only to the current web application (ServletContext), so information stored in one context will not be directly visible in another. This means that if a user logs on to one of the applications on my server their user information is not available to any other applications running on the same server.
The following was ripped from the spring-reference.pdf available on the www.springframework.org website. The purpose of this blog entry is simply to remind myself what the properties are for transactions when defining them within the applicationContext.xml file.
I also wanted to give myself some examples from actual running code, in this case, from the JPetstore Sample Application provided by Spring.
The TransactionDefinition interface specifies:
• Transaction isolation: The degree of isolation this transaction has from the work of other transactions. For
example, can this transaction see uncommitted writes from other transactions?
• Transaction propagation: Normally all code executed within a transaction scope will run in that
transaction. However, there are several options specificying behaviour if a transactional method is executed
when a transaction context already exists: For example, simply running in the existing transaction (the most
common case); or suspending the existing transaction and creating a new transaction. Spring offers the
transaction propagation options familiar from EJB CMT.
• Transaction timeout: How long this transaction may run before timing out (automatically being rolled
back by the underlying transaction infrastructure).
• Read-only status: A read-only transaction does not modify any data. Read-only transactions can be a
useful optimization in some cases (such as when using Hibernate).
<!-- - A parent bean definition which is a base definition for transaction proxies. - It is markes as abstract, since it is never supposed to be instantiated itself. - We set shared transaction attributes here, following our naming patterns. - The attributes can still be overridden in child bean definitions. -->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager"><ref bean="transactionManager"></ref>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</property>
<bean id="petStore" parent="baseTransactionProxy">
<property name="target">
<bean class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
<property name="accountDao"><ref bean="accountDao"/></property>
<property name="categoryDao"><ref bean="categoryDao"/></property>
<property name="productDao"><ref bean="productDao"/></property>
<property name="itemDao"><ref bean="itemDao"/></property>
<property name="orderDao"><ref bean="orderDao"/></property>
</bean>
</property>
Websphere Application Server 5.1 woes
When attempting to install a new application using an EAR file created by Websphere Studio 5.1 I get the following security warning. When I finish the installation of the new application I am unable to start the application from the enterprise application panel. I am at a loss for what I must do.
The contents of the was.policy file -
//
// Template policy file for enterprise application.
// Extra permissions can be added if required by the enterprise application.
//
// NOTE: Syntax errors in the policy files will cause the enterprise application FAIL to start.
// Extreme care should be taken when editing these policy files. It is advised to use
// the policytool provided by the JDK for editing the policy files
// (WAS_HOME/java/jre/bin/policytool).
//
grant codeBase "file:${application}" {
};
grant codeBase "file:${jars}" {
};
grant codeBase "file:${connectorComponent}" {
};
grant codeBase "file:${webComponent}" {
};
grant codeBase "file:${ejbComponent}" {
};
ADMA0080W: A template policy file without any permission set is included in the 1.2.x enterprise application. You can modify the Java 2 Security policy for the enterprise application by editing the was.policy file located in the ${user.install.root}/config/cells/(yourCellName)/applications/(yourAppName).ear/deployments/(yourAppName)/META-INF directory after the application is installed. For syntax of was.policy, please refer to the Dynamic Policy section of documentation in Info Center.
Solution:
Well, after some time playing with the Webphere Application Server 5.1 install I realized that when I was exporting the application from Webphere Studio 5.1 I was not exporting from the EAR project name but the Sub-Project name in my tree menu. I also realized that I was attemting to add a project to the Application Server that had the same name as an application currently running on the application server. This is a big no-no and the reason for my Webphere Application Server 5.1 woes. I renamed the project in Webphere Studio 5.1 and also created a new Enterprise Application Project for good measure called DFS and DFSEAR respectively. Then I exported by right clicking the DFSEAR project and choosing (surprise) "export". Then I went to install the application on the Websphere Application Server 5.1 and everything fired up correctly.
What is left to do?
I need to be able to invoke my new application without including the port number 9080 in my url line. I am running IBM HTTP SERVER 2.1.4 and I need to be able to invoke the files running on IBM WAS 5.1 without the 9080 port number.
Validator: Using A ValidWhen Edit
I was receiving a server error after adding a "validwhen" edit to my validation.xml file that looked like the following.
<field property="employmentHistoryDate" depends="validwhen">
<msg name="validwhen" key="error.employee.employmentHistoryDate.blank">
<var>
<var-name>test</var-name>
<var-value>((employeeHistory == "C") or (*this* == null))</var-value>
</var>
</msg>
</field>
</code>
I thought that my syntax was incorrect so I spent some time reviewing the information on the Validator website for the validwhen edit.
http://struts.apache.org/userGuide/dev_validator.html
After adding an edit to my validation.xml that was a carbon copy of an example in the userGuide and still receiving the excetpion I realized that there must be something else going on. I noticed a reference in the first line of the exception that had the name "antlr". I did a search for Validator and "antlr" and I came across a JavaRanch message that said that you must have the "antlr.jar" file in your "lib" folderif you wish to use "validwhen". I then searched and found the "antlr" website at www.antlr.org and downloaded the "antlr" .zip file and placed antlr.jar in my lib folder. Now my "Validwhen" edits work like a charm.
More Info on ANTLR below and on the website.
ANTLR Parser Generator and Translator Generator Home Page
ANTLR Parser Generator and Translator Generator Home Page: "ANTLR, ANother Tool for Language Recognition, (formerly PCCTS) is a language tool that provides a framework for constructing recognizers, compilers, and translators from grammatical descriptions containing Java, C#, or C actions. ANTLR provides excellent support for tree construction, tree walking, and translation. There are currently about 5,000 ANTLR source downloads a month. "
PreparedStatement TIME and DATE field
I have reached an error in my Spring JDBC DAO layer when attempting to create a prepared statement for a TIME field going against a DB2 database (v6.1). I believe that I need to intantiate the java field as a java.sql.Time object. Then pass this directly into the prepared statement and allow the DB2Java driver to take over and convert this into the time value that will ultimately get stored in the database. I found the following information on a web page: http://www.cs.tut.fi/lintula/manual/java/jdbc/jdbcprguide.htm
SOLID JDBC Driver Programmer's Guide: "Statement with parameters
The code below creates a PreparedStatement object for a query, assigns values for its parameters and executes the query. Check the the available methods for setting values to different column types from JDBC Type Conversion Matrix . The code expects a Connection object conn to be established.
PreparedStatement pstmt;
int count, cnt;
int i;
sQuery = 'INSERT INTO ALLTYPES (TI,SI,II,RR,FF,DP,DE,NU,CH,VC,DT,TM,TS) VALUES ';
sQuery = sQuery '(?,?,?,?,?,?,?,?,?,?,?,?,?)';
pstmt= conn.prepareStatement(sQuery);
pstmt.setInt(1,101);
pstmt.setInt(2,102);
pstmt.setInt(3,103);
pstmt.setDouble(4,2104.56);
pstmt.setDouble(5,104.56);
pstmt.setDouble(6,3104.56);
pstmt.setDouble(7,204.56);
pstmt.setDouble(8,304.56);
pstmt.setString(9,'cccc');
pstmt.setString(10,'longer string');
java.sql.Time pTime = new java.sql.Time(11,11,11);
java.sql.Date pDate = new java.sql.Date(96,1,2);
java.sql.Timestamp pTimestamp = new java.sql.Timestamp(96,1,2,11,11,11,0);
pstmt.setDate(11,pDate);
pstmt.setTime(12,pTime);
pstmt.setTimestamp(13,pTimestamp);
pstmt.executeUpdate();
See source code for example application sample3.
Note that the insert is not committed by the code unless the database is in autocommit mode."
********************************************************************************
Solution!!!
This was strictly a JAVA issue. What happens with the SQL Driver is that it attempts to convert the Java field that we are passing into the preparedStatement into the correct SQLParameter.
Type.VARCHAR would result in a (Object instanceof String) call.
Type.TIME would result in a (Object instanceof Time) call.
Our java fields are strings so that they can be formatted properly for DB2. That means that we can only describe our DATE and TIME fields as Type.VARCHAR or else we will get a "Program type out of range error".
org.springframework.jdbc.UncategorizedSQLException: (executing PreparedStatementCallback [PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=[UPDATE PBBA.BBAB20H SET BBAB20H_CDVLDT = ?,BBAB20H_DCUPDT = ?,BBAB20H_TMUPDT = ?,BBAB20H_IDUPDT = ? WHERE BBAB20H_CDFSYR = ? AND BBAB20H_NODOCU = ?]: params=[CHG,09/09/1999,10:38:40,CTK552,2005,090250074]]): encountered SQLException [[IBM][JDBC Driver] CLI0613E Program type out of range. SQLSTATE=S1003]; nested exception is COM.ibm.db2.jdbc.app.DB2Exception: [IBM][JDBC Driver] CLI0613E Program type out of range. SQLSTATE=S1003
COM.ibm.db2.jdbc.app.DB2Exception: [IBM][JDBC Driver] CLI0613E Program type out of range. SQLSTATE=S1003
at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.pstmtException(SQLExceptionGenerator.java:436)
at COM.ibm.db2.jdbc.app.DB2PreparedStatement.setTargetType(DB2PreparedStatement.java:2280)
at COM.ibm.db2.jdbc.app.DB2PreparedStatement.setObject(DB2PreparedStatement.java:1939)
at COM.ibm.db2.jdbc.app.DB2PreparedStatement.setObject(DB2PreparedStatement.java:1832)
at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.setValues(PreparedStatementCreatorFactory.java:188)
at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.createPreparedStatement(PreparedStatementCreatorFactory.java:170)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:286)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:418)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:434)
at org.springframework.jdbc.object.SqlUpdate.update(SqlUpdate.java:152)
at edu.uga.busfin.dao.jdbc.CommonDAOJdbc$BudgetAmendmentAuditUpdate.update(CommonDAOJdbc.java:102)
at edu.uga.busfin.dao.jdbc.CommonDAOJdbc.updateBudgetAmendmentAudit(CommonDAOJdbc.java:61)
at edu.uga.busfin.dao.CommonDAOTest.testUpdateBudgetAmendmentAudit(CommonDAOTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
So from here on out our DATE cols and TIME cols in our database must be described in our prepared statement as Type.VARCHAR and the java field must be of type String.
protected BudgetAmendmentAuditUpdate(DataSource ds){
super(ds,"UPDATE PBBA.BBAB20H SET " +
"BBAB20H_CDVLDT = ?," +
"BBAB20H_DCUPDT = ?," +
"BBAB20H_TMUPDT = ?," +
"BBAB20H_IDUPDT = ? " +
"WHERE BBAB20H_CDFSYR = ? AND BBAB20H_NODOCU = ?");
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Validation Status
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Date Updated (MUST BE A VARCHAR)
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Time Updated (MUST BE A VARCHAR)
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Updated By
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Fiscal Year
this.declareParameter(new SqlParameter(Types.VARCHAR)); // Document Number
this.compile();
}
