Thanks for your reply,I have implements ApplicationServlet basing GAEApplicationServlet codebase.and This work fine.
Here is the my code:
public class MemcachedApplicationServlet extends ApplicationServlet {
private static final Logger logger = Logger.getLogger(MemcachedApplicationServlet.class.getName());
// memcache mutex is MUTEX_BASE + sessio id
private static final String MUTEX_BASE = "_vmutex";
// used identify ApplicationContext in memcache and datastore
private static final String AC_BASE = "_vac";
// UIDL requests will attempt to gain access for this long before telling
// the client to retry
private static final int MAX_UIDL_WAIT_MILLISECONDS = 5000;
// Tell client to retry after this delay.
// Note: currently interpreting Retry-After as ms, not sec
private static final int RETRY_AFTER_MILLISECONDS = 100;
// Properties used in the datastore
private static final String PROPERTY_EXPIRES = "expires";
private static final String PROPERTY_DATA = "data";
// path used for cleanup
private static final String CLEANUP_PATH = "/CLEAN";
// max entities to clean at once
private static final int CLEANUP_LIMIT = 200;
// appengine session kind
private static final String APPENGINE_SESSION_KIND = "_ah_SESSION";
// appengine session expires-parameter
private static final String PROPERTY_APPENGINE_EXPIRES = "_expires";
private static int count = 0;
private static Object LOCK = new Object();
protected void sendDeadlineExceededNotification(HttpServletRequest request,
HttpServletResponse response) throws IOException {
criticalNotification(
request,
response,
"Deadline Exceeded",
"I'm sorry, but the operation took too long to complete. We'll try reloading to see where we're at, please take note of any unsaved data...",
"", null);
}
protected void sendNotSerializableNotification(HttpServletRequest request,
HttpServletResponse response) throws IOException {
criticalNotification(
request,
response,
"NotSerializableException",
"I'm sorry, but there seems to be a serious problem, please contact the administrator. And please take note of any unsaved data...",
"", getApplicationUrl(request).toString()
+ "?restartApplication");
}
protected void sendCriticalErrorNotification(HttpServletRequest request,
HttpServletResponse response) throws IOException {
criticalNotification(
request,
response,
"Critical error",
"I'm sorry, but there seems to be a serious problem, please contact the administrator. And please take note of any unsaved data...",
"", getApplicationUrl(request).toString()
+ "?restartApplication");
}
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
initPool();
if (isCleanupRequest(request)) {
cleanDatastore();
return;
}
RequestType requestType = getRequestType(request);
if (requestType == RequestType.STATIC_FILE) {
// no locking needed, let superclass handle
super.service(request, response);
cleanSession(request);
return;
}
if (requestType == RequestType.APPLICATION_RESOURCE) {
// no locking needed, let superclass handle
getApplicationContext(request);
super.service(request, response);
cleanSession(request);
return;
}
final HttpSession session = request
.getSession(requestCanCreateApplication(request, requestType));
if (session == null) {
handleServiceSessionExpired(request, response);
cleanSession(request);
return;
}
long startTime = System.currentTimeMillis();
try {
// de-serialize or create application context, store in session
ApplicationContext ctx = getApplicationContext(request);
super.service(request, response);
// serialize
String id = AC_BASE + session.getId();
mc.set(id, ctx);
} catch (NotSerializableException e) {
logger.log(Level.SEVERE, "Not serializable!", e);
// TODO this notification is usually not shown - should we redirect
// in some other way - can we?
sendNotSerializableNotification(request, response);
} catch (Exception e) {
logger.log(Level.WARNING,
"An exception occurred while servicing request.", e);
sendCriticalErrorNotification(request, response);
} finally {
// "Next, please!"
cleanSession(request);
long endTime = System.currentTimeMillis();
synchronized (LOCK) {
count++;
System.out.println("count:" + count + ",time:" + (endTime - startTime) + "ms\n");
}
}
}
protected ApplicationContext getApplicationContext(HttpServletRequest request) {
HttpSession session = request.getSession();
String id = AC_BASE + session.getId();
ApplicationContext applicationContext = (ApplicationContext) mc.get(id);
if (applicationContext != null) {
session.setAttribute(WebApplicationContext.class.getName(),
applicationContext);
}
// will create new context if the above did not
return getApplicationContext(session);
}
private boolean isCleanupRequest(HttpServletRequest request) {
String path = getRequestPathInfo(request);
if (path != null && path.equals(CLEANUP_PATH)) {
return true;
}
return false;
}
/**
* Removes the ApplicationContext from the session in order to minimize the
* data serialized to datastore and memcache.
*
* @param request
*/
private void cleanSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(WebApplicationContext.class.getName());
}
}
/**
* This will look at the timestamp and delete expired persisted Vaadin and
* appengine sessions from the datastore.
* <p/>
* TODO Possible improvements include: 1. Use transactions (requires entity
* groups - overkill?) 2. Delete one-at-a-time, catch possible exception,
* continue w/ next.
*/
private void cleanDatastore() {
//TODO
}
protected MemCachedClient mc = null;
protected void initPool() {
if (mc == null) {
ServletContext servletContext = getServletContext();
org.springframework.context.ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
mc = (MemCachedClient) applicationContext.getBean("memcachedClient");
}
}
}