All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zkoss.zk.ui.http.DHtmlLayoutServlet Maven / Gradle / Ivy

There is a newer version: 10.0.0-jakarta
Show newest version
/* DHtmlLayoutServlet.java

	Purpose:
		
	Description:
		
	History:
		Mon May 30 21:11:28     2005, Created by tomyeh

Copyright (C) 2005 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
	This program is distributed under LGPL Version 2.1 in the hope that
	it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zk.ui.http;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.LoggerFactory;

import org.zkoss.lang.Exceptions;
import org.zkoss.lang.Expectable;
import org.zkoss.mesg.Messages;
import org.zkoss.web.servlet.Servlets;
import org.zkoss.web.servlet.http.Https;
import org.zkoss.zk.mesg.MZk;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.OperationException;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.Richlet;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.WebApp;
import org.zkoss.zk.ui.impl.RequestInfoImpl;
import org.zkoss.zk.ui.metainfo.PageDefinition;
import org.zkoss.zk.ui.metainfo.PageDefinitions;
import org.zkoss.zk.ui.sys.RequestInfo;
import org.zkoss.zk.ui.sys.SessionCtrl;
import org.zkoss.zk.ui.sys.SessionsCtrl;
import org.zkoss.zk.ui.sys.UiFactory;
import org.zkoss.zk.ui.sys.WebAppCtrl;
import org.zkoss.zk.ui.util.Configuration;
import org.zkoss.zk.ui.util.DesktopRecycle;

/**
 * Used to process the request for a ZUML page. Though it is called
 * DHtmlLayoutServlet, it is used to serve all kind of HTTP-based clients,
 * including ajax (HTML+Ajax), mil (Mobile Interactive Language)
 * and others (see {@link Desktop#getDeviceType}.
 *
 * 

Init parameters: * *

*
update-uri
*
It specifies the URI which the ZK AU engine is mapped to.
*
compress
*
It specifies whether to compress the output if the browser supports the compression (Accept-Encoding) and this Servlet is not included by other Servlets.
*
log-level
*
It specifies the default log level for org.zkoss. If not specified, the system default (usually INFO) is used.
*
* @author tomyeh */ public class DHtmlLayoutServlet extends HttpServlet { private static final org.slf4j.Logger log = LoggerFactory.getLogger(DHtmlLayoutServlet.class); private WebManager _webman; private boolean _webmanCreated; private boolean _compress = true; //Servlet// @SuppressWarnings("deprecation") public void init() throws ServletException { final ServletConfig config = getServletConfig(); String param = config.getInitParameter("log-level"); if (param != null && param.length() > 0) { final Level level = org.zkoss.util.logging.Log.getLevel(param); if (level != null) Logger.getLogger("org.zkoss").setLevel(level); else log.error("Unknown log-level: " + param); } param = config.getInitParameter("compress"); _compress = param == null || param.length() == 0 || "true".equals(param); final ServletContext ctx = getServletContext(); _webman = WebManager.getWebManagerIfAny(ctx); String updateURI = Utils.checkUpdateURI(config.getInitParameter("update-uri"), "The update-uri parameter"); ctx.setAttribute("org.zkoss.zk.ui.http.update-uri", updateURI); //B65-ZK-1619 String resourceURI = config.getInitParameter("resource-uri"); if (resourceURI == null) resourceURI = updateURI; else resourceURI = Utils.checkUpdateURI(resourceURI, "The resource-uri parameter"); if (_webman == null) { log.warn("WebManager not initialized. Please check if HttpSessionListener is configured properly."); _webman = new WebManager(ctx, updateURI, resourceURI); _webmanCreated = true; } else { _webman.setUpdateUri(updateURI); _webman.setResourceUri(resourceURI); } } public void destroy() { if (_webman != null) { if (_webmanCreated) _webman.destroy(); _webman = null; } } //-- super --// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = Https.getThisPathInfo(request); final boolean bRichlet = path != null && path.length() > 0; if (!bRichlet) path = Https.getThisServletPath(request); // if (log.finerable()) log.finer("Creates from "+path); final Session sess = WebManager.getSession(getServletContext(), request); if (!SessionsCtrl.requestEnter(sess)) { response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, Messages.get(MZk.TOO_MANY_REQUESTS)); return; } try { final Object old = I18Ns.setup(sess, request, response, sess.getWebApp().getConfiguration().getResponseCharset()); try { if (!process(sess, request, response, path, bRichlet)) handleError(sess, request, response, path, null); } catch (Throwable ex) { handleError(sess, request, response, path, ex); } finally { I18Ns.cleanup(request, old); } } finally { SessionsCtrl.requestExit(sess); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } //-- private --// /** * Process the request. * @return false if the page is not found. * @since 3.0.0 */ protected boolean process(Session sess, HttpServletRequest request, HttpServletResponse response, String path, boolean bRichlet) throws ServletException, IOException { final WebApp wapp = sess.getWebApp(); final WebAppCtrl wappc = (WebAppCtrl) wapp; final Configuration config = wapp.getConfiguration(); final boolean bInclude = Servlets.isIncluded(request); final boolean compress = _compress && !bInclude; final Writer out = compress ? (Writer) new StringWriter() : response.getWriter(); final DesktopRecycle dtrc = bInclude ? null : config.getDesktopRecycle(); final ServletContext ctx = getServletContext(); Desktop desktop = dtrc != null ? DesktopRecycles.beforeService(dtrc, ctx, sess, request, response, path) : null; try { if (desktop != null) { //recycle final Page page = Utils.getMainPage(desktop); if (page != null) { final Execution exec = new ExecutionImpl(ctx, request, response, desktop, page); WebManager.setDesktop(request, desktop); wappc.getUiEngine().recycleDesktop(exec, page, out); } else desktop = null; //something wrong (not possible; just in case) } // check voided for ZK-2352: Executions.forward() will show IOException warning boolean voided = false; if (desktop == null) { desktop = _webman.getDesktop(sess, request, response, path, true); if (desktop == null) //forward or redirect return true; final RequestInfo ri = new RequestInfoImpl(wapp, sess, desktop, request, PageDefinitions.getLocator(wapp, path)); ((SessionCtrl) sess).notifyClientRequest(true); final UiFactory uf = wappc.getUiFactory(); if (uf.isRichlet(ri, bRichlet)) { final Richlet richlet = uf.getRichlet(ri, path); if (richlet == null) return false; //not found final Page page = WebManager.newPage(uf, ri, richlet, response, path); final Execution exec = new ExecutionImpl(ctx, request, response, desktop, page); wappc.getUiEngine().execNewPage(exec, richlet, page, out); //no need to set device type here, since UiEngine will do it later } else { final PageDefinition pagedef = uf.getPageDefinition(ri, path); if (pagedef == null) return false; //not found final Page page = WebManager.newPage(uf, ri, pagedef, response, path); final Execution exec = new ExecutionImpl(ctx, request, response, desktop, page); wappc.getUiEngine().execNewPage(exec, pagedef, page, out); voided = exec.isVoided(); } } // check voided to ignore the IOExecuption that caused by Executions.forward() if (compress && !voided) { final String result = ((StringWriter) out).toString(); try { final OutputStream os = response.getOutputStream(); //Call it first to ensure getWrite() is not called yet byte[] data = result.getBytes(config.getResponseCharset()); if (data.length > 200) { byte[] bs = Https.gzip(request, response, null, data); if (bs != null) data = bs; //yes, browser support compress } response.setContentLength(data.length); os.write(data); response.flushBuffer(); } catch (IllegalStateException ex) { //getWriter is called response.getWriter().write(result); } } } finally { if (dtrc != null) DesktopRecycles.afterService(dtrc, desktop); } return true; //success } /** Handles exception being thrown when rendering a page. * @param err the exception being throw. If null, it means the page * is not found. */ private void handleError(Session sess, HttpServletRequest request, HttpServletResponse response, String path, Throwable err) throws ServletException, IOException { Utils.resetOwner(); // ZK-3679 Throwable cause; if (err instanceof OperationException && (cause = err.getCause()) instanceof Expectable) err = cause; //Note: if not included, it is handled by Web container if (err != null && Servlets.isIncluded(request)) { //Bug 1714094: we have to handle err, because Web container //didn't allow developer to intercept errors caused by inclusion final String errpg = sess.getWebApp().getConfiguration().getErrorPage(sess.getDeviceType(), err); if (errpg != null) { try { request.setAttribute("javax.servlet.error.message", Exceptions.getMessage(err)); request.setAttribute("javax.servlet.error.exception", err); request.setAttribute("javax.servlet.error.exception_type", err.getClass()); request.setAttribute("javax.servlet.error.status_code", new Integer(500)); if (process(sess, request, response, errpg, false)) return; //done log.warn("The error page not found: " + errpg); } catch (IOException ex) { //eat it (connection off) } catch (Throwable ex) { log.warn("Failed to load the error page: " + errpg, ex); } } } Utils.handleError(getServletContext(), request, response, path, err); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy