Sunday, November 23, 2014
Java Objects to XML and XML to Java Objects - XStream
import java.io.File;
public static Document readFromXml(String input) throws InvalidDataException {
public static String initializeAndWriteToXml(Object objectToWrite) {
public static <T> T readFromXml(String xmlContent, Class<T> targetObjectClass) {
Thursday, November 20, 2014
JSON to HashMap - Parsing JSON String
Recursivey Parsing JSON String to HashMap
Json String can contain JsonArray, JsonObject etc.
package com.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
public class TestJson{
public static void main(String args[]) throws Exception {
JSONObject jsonObject = new JSONObject(
"{\"A\":\"M1\",\"Data\":[ {\"B\":[{ \"B1\":\"111\",\"B2\":\"Warning \"},{ \"B1\":\"222\",\"B2\":\"Warning \"}],\"C\":[{\"c1\":\"IL2\",\"c2\":\"[0.750183,0.00933380975964486]\"},{\"c1\":\"IL1b\",\"c2\":\"[0.750183,-1.5216938335421]\"}]}]}");
System.out.println(getMap(jsonObject));
}
private static Map getMap(JSONObject object) {
Map<String, Object> map = new HashMap<String, Object>();
Object jsonObject = null;
String key = null;
Object value = null;
try {
Iterator<String> keys = object.keys();
while (keys.hasNext()) {
key = null;
value = null;
key = keys.next();
if (null != key && !object.isNull(key)) {
value = object.get(key);
}
if (value instanceof JSONObject) {
map.put(key, getMap((JSONObject) value));
continue;
}
if (value instanceof JSONArray) {
JSONArray array = ((JSONArray) value);
List list = new ArrayList();
for (int i = 0 ; i < array.length() ; i++) {
jsonObject = array.get(i);
if (jsonObject instanceof JSONObject) {
list.add(getMap((JSONObject) jsonObject));
} else {
list.add(jsonObject);
}
}
map.put(key, list);
continue;
}
map.put(key, value);
}
} catch (Exception e) {
System.out.println(e);
}
return map;
}
}
How to avoid extra POJO's / Classes
package com.package;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
public class Test{
public static void main(String[] args) {
String json = "[{\"givenName\": \"Adrienne H.\",\"surname\": \"Kovacs\"},{\"givenName\": \"Philip\",\"surname\": \"Moons\"}]";
ObjectMapper mapper = new ObjectMapper();
List<Author> list = new ArrayList<Author>();
try {
list = mapper.readValue(json, TypeFactory.defaultInstance().constructCollectionType(List.class, Author.class));
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(list);
}
}
So here i do not need to map List<Author> inside any other class.
Tuesday, November 18, 2014
Validate Date against given Date Format
How to validate given Date against Date Format.
SO there are two approaches,
1.) Using SimpleDateFormat
2.) Using Regex.
Basic Example.
SO there are two approaches,
1.) Using SimpleDateFormat
2.) Using Regex.
Basic Example.
SimpleDateFormat
Date date = null; boolean checkformat; try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/dd/MM"); dateFormat.setLenient(false); date = dateFormat.parse("2013/25/09"); } catch (ParseException ex) { ex.printStackTrace(); } if (date == null) { checkformat = false; } else { checkformat = true; } System.out.println(checkformat);
Regex based
public static void main(String[] args) throws ParseException { String input = "2014/12/31"; boolean checkformat; if (input.matches("([0-9]{4})/([0-9]{2})/([0-9]{2})")) // for yyyy/MM/dd format checkformat = true; else checkformat = false; System.out.println(checkformat); }
Play around the {2}, {2}, {4}
values inside curly braces to prepare regex.
Complexity Increases, let say i have many Date Formats.
public
class
DateUtil {
// List of all date formats that we want to parse.
// Add your own format here.
private
static
List<SimpleDateFormat>;
dateFormats =
new
ArrayList<SimpleDateFormat>() {{
add(
new
SimpleDateFormat(
"M/dd/yyyy"
));
add(
new
SimpleDateFormat(
"dd.M.yyyy"
));
add(
new
SimpleDateFormat(
"M/dd/yyyy hh:mm:ss a"
));
add(
new
SimpleDateFormat(
"dd.M.yyyy hh:mm:ss a"
));
add(
new
SimpleDateFormat(
"dd.MMM.yyyy"
));
add(
new
SimpleDateFormat(
"dd-MMM-yyyy"
));
}
};
/**
* Convert String with various formats into java.util.Date
*
* @param input
* Date as a string
* @return java.util.Date object if input string is parsed
* successfully else returns null
*/
public
static
Date convertToDate(String input) {
Date date =
null
;
if
(
null
== input) {
return
null
;
}
for
(SimpleDateFormat format : dateFormats) {
try
{
format.setLenient(
false
);
date = format.parse(input);
}
catch
(ParseException e) {
//Shhh.. try other formats
}
if
(date !=
null
) {
break
;
}
}
return
date;
}
}
// Test class to test out
public
class
TestDateUtil {
public
static
void
main(String[] args) {
System.out.println(
"10/14/2012"
+
" = "
+ DateUtil.convertToDate(
"10/14/2012"
));
System.out.println(
"10-Jan-2012"
+
" = "
+ DateUtil.convertToDate(
"10-Jan-2012"
));
System.out.println(
"01.03.2002"
+
" = "
+ DateUtil.convertToDate(
"01.03.2002"
));
System.out.println(
"12/03/2010"
+
" = "
+ DateUtil.convertToDate(
"12/03/2010"
));
System.out.println(
"19.Feb.2011"
+
" = "
+ DateUtil.convertToDate(
"19.Feb.2011"
));
System.out.println(
"4/20/2012"
+
" = "
+ DateUtil.convertToDate(
"4/20/2012"
));
System.out.println(
"some string"
+
" = "
+ DateUtil.convertToDate(
"some string"
));
System.out.println(
"123456"
+
" = "
+ DateUtil.convertToDate(
"123456"
));
System.out.println(
"null"
+
" = "
+ DateUtil.convertToDate(
null
));
}
}
Location:
Japan
Java Design Pattern - Factory pattern
Background information
This pattern introduces loose coupling between classes which is the most important principle one should consider and apply while designing the application architecture. Loose coupling can be introduced in application architecture by programming against abstract entities rather than concrete implementations. This not only makes our architecture more flexible but also less fragile.A picture is worth thousand words. Lets see how a factory implementation will look like.
Above class diagram depicts a common scenario using example of car factory which is able to build 3 types of cars i.e. small, sedan and luxury. Building a car requires many steps from allocating accessories to final makeup. These steps can be written in programming as methods and should be called while creating an instance of a specific car type.
If we are unfortunate then we will create instances of car types (e.g. SmallCar) in our application classes and thus we will expose the car building logic to outside world and this is certainly not good. It also prevents us in making changes to car making process because code in not centralized, and making changes in all composing classes seems not feasible.
Implementation
So far we have seen the classes need to be designed for making a CarFactory. Lets hit the keyboard now and start composing our classes.CarType.java will hold the types of car and will provide car types to all other classes
package designPatterns.factory;
public enum CarType {
SMALL, SEDAN, LUXURY
}
Car.java is parent class of all car instances and it will also contain the common logic applicable in car making of all types.
package designPatterns.factory;
public abstract class Car {
public Car(CarType model) {
this.model = model;
arrangeParts();
}
private void arrangeParts() {
// Do one time processing here
}
// Do subclass level processing in this method
protected abstract void construct();
private CarType model = null;
public CarType getModel() {
return model;
}
public void setModel(CarType model) {
this.model = model;
}
}
LuxuryCar.java is concrete implementation of car type LUXURY
package designPatterns.factory;
public class LuxuryCar extends Car {
LuxuryCar() {
super(CarType.LUXURY);
construct();
}
@Override
protected void construct() {
System.out.println("Building luxury car");
// add accessories
}
}
SmallCar.java is concrete implementation of car type SMALL
package designPatterns.factory;
public class SmallCar extends Car {
SmallCar() {
super(CarType.SMALL);
construct();
}
@Override
protected void construct() {
System.out.println("Building small car");
// add accessories
}
}
SedanCar.java is concrete implementation of car type SEDAN
package designPatterns.factory;
public class SedanCar extends Car {
SedanCar() {
super(CarType.SEDAN);
construct();
}
@Override
protected void construct() {
System.out.println("Building sedan car");
// add accessories
}
}
CarFactory.java is our main class implemented using factory pattern. It instantiates a car instance only after determining its type.
package designPatterns.factory;
public class CarFactory {
public static Car buildCar(CarType model) {
Car car = null;
switch (model) {
case SMALL:
car = new SmallCar();
break;
case SEDAN:
car = new SedanCar();
break;
case LUXURY:
car = new LuxuryCar();
break;
default:
// throw some exception
break;
}
return car;
}
}
In TestFactoryPattern.java, we will test our factory code. Lets run this class.
package designPatterns.factory;
public class TestFactoryPattern {
public static void main(String[] args) {
System.out.println(CarFactory.buildCar(CarType.SMALL));
System.out.println(CarFactory.buildCar(CarType.SEDAN));
System.out.println(CarFactory.buildCar(CarType.LUXURY));
}
}
Output:
Building small car
designPatterns.factory.SmallCar@7c230be4
Building sedan car
designPatterns.factory.SedanCar@60e1e567
Building luxury car
designPatterns.factory.LuxuryCar@e9bfee2
As you can see, factory is able to return any type of car instance it is requested for. It will help us in making any kind of changes in car making process without even touching the composing classes i.e. classes using CarFactory.
Advantages of factory pattern
By now, you should be able to count the main advantages of using factory pattern. Lets note down:- The creation of an object precludes its reuse without significant duplication of code.
- The creation of an object requires access to information or resources that should not be contained within the composing class.
- The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the application.
Monday, September 15, 2014
Type Casting in Java - Casting one Class to other class or interface
Type Casting in Java - Casting one Class to other class or interface
Type casting in Java is to cast one type, a class or interface, into
another type i.e. another class or interface. Since Java is an Object oriented
programming language and supports both Inheritance and Polymorphism, It’s easy that
Super class reference variable is pointing to Sub Class object but catch here
is that there is no way for Java compiler to know that a Super class variable is
pointing to Sub Class object. Which means you can not call method which is
declared on sub class. In order to do that, you first need to cast the Object back into its original
type. This is called type-casting in Java. This will be more clear when
we see an example of type casting in next section. Type casting comes with risk
of ClassCastException in Java, which is quite common with method which
accept Object type and later type cast into more specific type. we will see
when ClassCastException comes during type casting and How to avoid it in
coming section of this article. Another
worth noting point here is that from Java 5 onwards you can use Generics to write type-safe code
to reduce amount of type casting in Java which also reduces risk of java.lang.ClassCastException at
runtime.
What is type casting in Java
From first paragraph, we pretty much know What is type casting in Java. Anyway, In simple words type casting
is process of converting one type, which could be a class or interface to another, But as
per rules of Java programming language only classes or interfaces (collectively
known as Type) from same Type hierarchy can be cast or converted into each
other. If you try to cast two object which doesn't share same type hierarchy,
i.e. there is no parent child relationship between them, you will get compile time error. On the
other hand if you type cast objects from same type hierarchy but the object
which you are casting are not of the same type on which you are casting then it
will throw ClassCastException in Java. Some people may ask
why do you need type casting? well
you need type casting to get access of fields and methods declared on target
type or class. You can not access them with any other type. Let's see a simple
example of type casting in Java with two classes Base and Derived which
shares same type hierarchy.
Type
casting example in Java
In this Example of type casting in Java we have two classes, Base and Derived. Derived class
extends Base i.e. Base is a Super class and Derived is a
Sub class. So there type hierarchy looks like following tree :
Base
|
Derived
Now look at following code :
Base b = new
Derived();
//reference variable of Base class points object
of Derived class
Derived d = b; //compile time error, requires casting
Derived d = (Derived) b; // type casting Base to Derived
Derived d = b; //compile time error, requires casting
Derived d = (Derived) b; // type casting Base to Derived
Above code type casting object of Derived class into
Base class and it will throw ClassCastExcepiton if b is not an
object of Derived class. If Base and Derived class are
not related to each other and doesn't part of same type hierarchy, cast will
throw compile time error. for example you can not cast String and StringBuffer, as
they are not from same type hierarchy.
Type-casting and ClassCastExcepiton in Java
As explained in last section type casting can result in ClassCastException in Java. If
the object you are casting is of
different type. ClassCastException is quite common while using
Java collection framework classes e.g. ArrayList, LinkedList or HashSet etc because they
accept object of type java.lang.Object, which allows insertion of any
object into collection. let's a real life example of ClassCastException in Java
during type casting :
ArrayList names = new
ArrayList();
names.add("abcd"); //adding String
names.add(1); //adding Integer
String name = (String) names.get(0); //OK
name = (String) names.get(1); // throw ClassCastException because you can not convert Integer to String
names.add("abcd"); //adding String
names.add(1); //adding Integer
String name = (String) names.get(0); //OK
name = (String) names.get(1); // throw ClassCastException because you can not convert Integer to String
In above example we have an ArrayList of String which
stores names. But we also added an incorrect name which is Integer and when
we retrieve Object from collection they are of type java.lang.Object which
needs to be cast on respective for performing operation. This leads into java.lang.ClassCastException when we
try to type cast second object, which is an Integer, into String. This problem
can be avoided by using Generics in Java which we will
see in next section.
Generics and Type Casting in Java
Generics was introduced in Java 5 along with another type-safe feature Enum, which ensures type
safety of code during compile time, So rather you getting ClassCastException during runtime
by type casting you get compile timer error why your code violate type safety.
Use of Generics also removes casting from many places e.g. now while retrieving
object from Collection you don't need to type cast into respective type. Here
is the modified version of same code which is free of ClassCastException because
use of Generics :
ArrayList<String> names = new ArrayList<String>(); //ArrayList of
String only accept String
names.add("abcd");
names.add(1); //compile time error you can not add Integer into ArrayList of String
String name = names.get(0); // no type casting requires
names.add("abcd");
names.add(1); //compile time error you can not add Integer into ArrayList of String
String name = names.get(0); // no type casting requires
If you are new to Generics, those angle bracket denotes type. to learn
more about Generics, See How Generics works in Java.
Friday, August 29, 2014
Spring MVC’s Default Behavior
View Resolver
First up is the view resolver. We can’t specify all the views ahead of time and the only way the marketing department communicates new pages to us is by publishing them into our JSP directory, Springs InternalResourceViewResolver is the perfect fit.<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/content/" /> <property name="suffix" value=".jsp" /> </bean> |
The Default Controller
Now that there is a view resolver capable of seeing all the pages produced by the marketing department, a controller must be created and mapped so that it will produce the correct view name.package com.sourceallies.base; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class DefaultController { @RequestMapping("/**/*") public void defaultRequest(){} } |
So at this point I now have a more complicated version of the normal servlet request process. Its usefulness becomes apparent when marketing needs a new piece of data on a specific page and I need to create a controller.
@Controller public class ProfileController { @RequestMapping("/members/profile.html") public void testRequest(Model model) { Profile profile = ...LookupProfile model.addAttribute("profile", profile); } } |
Wednesday, August 20, 2014
Understanding Spring MVC Model and Session Attributes
Spring MVC Scopes
When I started writing Web applications in Spring MVC, I found the Spring model and session attributes to be a bit of a mystery – especially as they relate to the HTTP request and session scopes and their attributes that I knew well. Was a Spring model element going to be found in my session or request? If so, how could I control this? In this post, I hope to demystify how Spring MVC’s model and session work.Spring’s @ModelAttribute
There are several ways to add data or objects to Spring’s model. Data or objects are typically added to Spring’s model via an annotated method in the controller. In the example below, @ModelAttribute is used to add an instance of MyCommandBean to the model under the key of “myRequestObject”.
@Controller
public class MyController {
@ModelAttribute("myRequestObject")
public MyCommandBean addStuffToRequestScope() {
System.out.println("Inside of addStuffToRequestScope");
MyCommandBean bean = new MyCommandBean("Hello World",42);
return bean;
}
@RequestMapping("/dosomething")
public String requestHandlingMethod(Model model, HttpServletRequest request) {
System.out.println("Inside of dosomething handler method");
System.out.println("--- Model data ---");
Map modelMap = model.asMap();
for (Object modelKey : modelMap.keySet()) {
Object modelValue = modelMap.get(modelKey);
System.out.println(modelKey + " -- " + modelValue);
}
System.out.println("=== Request data ===");
java.util.Enumeration reqEnum = request.getAttributeNames();
while (reqEnum.hasMoreElements()) {
String s = reqEnum.nextElement();
System.out.println(s);
System.out.println("==" + request.getAttribute(s));
}
return "nextpage";
}
// ... the rest of the controller
}
On an incoming request, any methods annotated with @ModelAttribute
are called before any controller handler method (like
requestHandlingMethod in the example above). These methods add data to a
java.util.Map that is added to the Spring model before the execution of
the handler method. This can be demonstrated by a simple experiment. I
created two JSP pages: index.jsp and nextpage.jsp. A link on
index.jsp page is used to send a request into the application triggering
the requestHandlingMethod() of MyController. Per the code above, the
requestHandlingMethod() returns “nextpage” as the logical name of the
next view which is resolved to nextpage.jsp in this case.
When this little Web site is executed in this fashion, the System.out.println’s of the controller, show how the @ModelAttribute method is executed before the handler method. It also shows that the MyCommandBean was created and added to Spring’s model and was available in the handler method.
When this little Web site is executed in this fashion, the System.out.println’s of the controller, show how the @ModelAttribute method is executed before the handler method. It also shows that the MyCommandBean was created and added to Spring’s model and was available in the handler method.
Inside of addStuffToRequestScope
Inside of dosomething handler method
--- Model data ---
myRequestObject -- MyCommandBean [someString=Hello World, someNumber=42]
=== Request data ===
org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE
==WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy
org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER
==org.springframework.web.servlet.theme.FixedThemeResolver@204af48c
org.springframework.web.servlet.DispatcherServlet.CONTEXT
==WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy
org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping
==dosomething.request
org.springframework.web.servlet.HandlerMapping.bestMatchingPattern
==/dosomething.*
org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER
==org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@18fd23e4
Now, the question is “where is Spring model data stored?” Is it
stored in the standard Java request scope? The answer is – yes…
eventually. As you can tell from the output above, MyCommandBean is in
the model, but not yet in the request object when the handler method
executes. Indeed, Spring does not add the model data to the request as
an attribute until after the execution of the handler method and before
presentation of the next view (in this case the nextpage.jsp).
This can also be demonstrated by printing out the attribute data stored in the HttpServletRequest in both index.jsp and nextpage.jsp. I arranged for both of these pages to use a JSP scriptlet (shown below) to display the HttpServletRequest attributes.
When the application comes up and index.jsp is displayed, you can see that there are no attributes in request scope.
In this case, when the “do something” link is clicked it causes the MyController’s handler method to execute, which in turn causes the nextpage.jsp to be displayed. Given the same JSP scriptlet is on the nextpage.jsp, it too renders what is in the request scope. Lo and behold, when nextpage.jsp renders, it shows the model MyCommandBean created in the controller has been added to the HttpServletRequest scope! The Spring model attribute key of “myRequestObject” has even been copied and used as the request attribute’s key.
So Spring model data created prior to (or during) the handler method execution has been copied to the HttpServletRequest before the next view is rendered.
Spring’s @SessionAttributes is used on a controller to designate which model attributes should be stored in the session.
In actually, what @SessionAttributes allows you to do is tell Spring which of your model attributes will also be copied to HttpSession before rendering the view. Again, this can be demonstrated with a little code.
In my index.jsp and nextpage.jsp, I added an additional JSP scriptlet to show the HttpSession attributes.
I annotated MyController with @SessionAttributes to put the same model attribute (myRequestObject) in Spring session.
This can also be demonstrated by printing out the attribute data stored in the HttpServletRequest in both index.jsp and nextpage.jsp. I arranged for both of these pages to use a JSP scriptlet (shown below) to display the HttpServletRequest attributes.
<hr />
<h3>Request Scope (key==values)</h3>
<%
java.util.Enumeration<String> reqEnum = request.getAttributeNames();
while (reqEnum.hasMoreElements()) {
String s = reqEnum.nextElement();
out.print(s);
out.println("==" + request.getAttribute(s));
%><br />
<%
}
%>
When the application comes up and index.jsp is displayed, you can see that there are no attributes in request scope.
In this case, when the “do something” link is clicked it causes the MyController’s handler method to execute, which in turn causes the nextpage.jsp to be displayed. Given the same JSP scriptlet is on the nextpage.jsp, it too renders what is in the request scope. Lo and behold, when nextpage.jsp renders, it shows the model MyCommandBean created in the controller has been added to the HttpServletRequest scope! The Spring model attribute key of “myRequestObject” has even been copied and used as the request attribute’s key.
So Spring model data created prior to (or during) the handler method execution has been copied to the HttpServletRequest before the next view is rendered.
Spring’s @SessionAttributes
So now you know how Spring’s model data is managed and how it relates to regular Http request attribute data. What about Spring’s session data?Spring’s @SessionAttributes is used on a controller to designate which model attributes should be stored in the session.
In actually, what @SessionAttributes allows you to do is tell Spring which of your model attributes will also be copied to HttpSession before rendering the view. Again, this can be demonstrated with a little code.
In my index.jsp and nextpage.jsp, I added an additional JSP scriptlet to show the HttpSession attributes.
<h3>Session Scope (key==values)</h3>
<%
java.util.Enumeration<String> sessEnum = request.getSession()
.getAttributeNames();
while (sessEnum.hasMoreElements()) {
String s = sessEnum.nextElement();
out.print(s);
out.println("==" + request.getSession().getAttribute(s));
%><br />
<%
}
%>
I annotated MyController with @SessionAttributes to put the same model attribute (myRequestObject) in Spring session.
@SessionAttributes("myRequestObject")
public class MyController {
...
}
I also added code to the handler method of my controller to show what
attributes are in HttpSession (just as it shows what attributes are in
HttpServletRequest).
So now, we should be able to see what is in the session object before, during, and after Spring MVC has handled one HTTP request when annotated with @SessionAttributes. The results are shown below. First, as the index.jsp page is displayed (before the request is sent and handled by Spring MVC), we see that there is no attribute data in either the HttpServletRequest or HttpSession.
During the execution of the handler method (requestHandlingMethod), you see MyCommandBean has been added to the Spring model attributes, but it is not yet in the HttpServletRequest or HttpSession scope.
But after the handler method has executed and when the nextpage.jsp is rendered, you can see that the model attribute data (MyCommandBean) has indeed been copied as an attribute (with the same attribute key) to both HttpServletRequest and HttpSession.
@SuppressWarnings("rawtypes")
@RequestMapping("/dosomething")
public String requestHandlingMethod(Model model, HttpServletRequest request, HttpSession session) {
System.out.println("Inside of dosomething handler method");
System.out.println("--- Model data ---");
Map modelMap = model.asMap();
for (Object modelKey : modelMap.keySet()) {
Object modelValue = modelMap.get(modelKey);
System.out.println(modelKey + " -- " + modelValue);
}
System.out.println("=== Request data ===");
java.util.Enumeration<String> reqEnum = request.getAttributeNames();
while (reqEnum.hasMoreElements()) {
String s = reqEnum.nextElement();
System.out.println(s);
System.out.println("==" + request.getAttribute(s));
}
System.out.println("*** Session data ***");
Enumeration<String> e = session.getAttributeNames();
while (e.hasMoreElements()){
String s = e.nextElement();
System.out.println(s);
System.out.println("**" + session.getAttribute(s));
}
return "nextpage";
}
So now, we should be able to see what is in the session object before, during, and after Spring MVC has handled one HTTP request when annotated with @SessionAttributes. The results are shown below. First, as the index.jsp page is displayed (before the request is sent and handled by Spring MVC), we see that there is no attribute data in either the HttpServletRequest or HttpSession.
During the execution of the handler method (requestHandlingMethod), you see MyCommandBean has been added to the Spring model attributes, but it is not yet in the HttpServletRequest or HttpSession scope.
But after the handler method has executed and when the nextpage.jsp is rendered, you can see that the model attribute data (MyCommandBean) has indeed been copied as an attribute (with the same attribute key) to both HttpServletRequest and HttpSession.
Controlling Session Attributes
So now you have an appreciation of how Spring model and session attribute data are added to HttpServletRequest and HttpSession. But now you may be concerned with how to manage that data in Spring session. Spring provides a means to remove Spring session attributes, and thereby also remove it from HttpSession (without having to kill the entire HttpSession). Simply add a Spring SessionStatus object as a parameter to a controller handler method. In this method, use the SessionStatus object to end the Spring session.
@RequestMapping("/endsession")
public String nextHandlingMethod2(SessionStatus status){
status.setComplete();
return "lastpage";
}
@RequestMapping("/endsession")
public String nextHandlingMethod2(SessionStatus status){
status.setComplete();
return "lastpage";
}
Subscribe to:
Posts (Atom)