Cambios en el comportamiento de un servlet

La implementación de Servlet 3.1 contiene cambios de comportamiento que pueden hacer que una aplicación escrita para el Servlet 3.0 se comporte de forma diferente o falle cuando se utiliza la característica Servlet 3.1 .

Puede elegir entre las implementaciones de características de Servlet 3.0 y Servlet 3.1 para cada instancia de servidor, teniendo en cuenta los cambios de comportamiento. Si el comportamiento necesario sólo se encuentra en la característica Servlet 3.1, debe utilizar la característica Servlet 3.1. Si una aplicación existente se ve afectada negativamente por los cambios de comportamiento en la característica Servlet 3.1, el uso de la característica Servlet 3.0 conserva el comportamiento existente para dicha aplicación. No puede utilizar las características Servlet 3.0 y Servlet 3.1 en el mismo servidor. Si configura ambas características, no se cargará ninguna característica de servlet.

Los cambios de comportamiento se han introducido por las siguientes razones:
  • Cambios necesarios para las aclaraciones en la especificación Servlet 3.1 .
  • Cambios necesarios para que la implementación pase el Servlet 3.1 Technology Compatibility Kit (TCK).
  • Cambios para mejorar la implementación del servlet.

Servlets, filtros y escuchas añadidos por programa

Una aclaración de la especificación Servlet 3.1 hace ahora ilegal que un ServletContextListener configure servlets, filtros o escuchas por programa si el ServletContextListener no se ha declarado en el archivo web.xml o en el archivo web-fragment.xml o no se ha anotado con @WebListener. Como resultado, cualquier llamada en el ServletContext para realizar una configuración programática de este tipo da como resultado una UnsupportedOperationException.

Reenvío después de iniciar el proceso asíncrono

En la implementación de Servlet 3.0, una respuesta siempre se cierra antes de que el método de reenvío de la interfaz RequestDispatcher efectúe el retorno. Sin embargo, debido a una aclaración en la especificación Servlet 3.1, la implementación de Servlet 3.1 no cierra o desecha la respuesta antes de que el método de reenvío de la interfaz RequestDispatcher efectúe el retorno, si la solicitud se sitúa en la modalidad asíncrona. Este cambio puede afectar a las aplicaciones 3.0 existentes, que añaden salida de respuesta en el retorno del reenvío porque ahora estos datos de respuesta se envían, mientras que en Servlet 3.0, no.

Conflictos de patrón de URL

En Servlet 3.0, una aplicación se inicia satisfactoriamente incluso cuando se ha correlacionado un patrón de URL con varios servlets. Sin embargo, debido a una aclaración en la especificación Servlet 3.1, la aplicación debe fallar al iniciarse. En la implementación de Liberty Servlet 3.1, se emite un mensaje y la aplicación no se inicia:
SRVE9016E: Unable to insert mapping [{0}] for servlet named [{1}]. The URL pattern is already defined for servlet named [{2}].

Explanation: There is an application error. A servlet mapping URL pattern should not map to multiple servlets.

User action: Change the URL pattern for the servlet mapping.

ServletContext.getMinorVersion()

En la implementación de la característica Servlet 3,0, esta API devuelve 0.

En la característica de Servlet 3.1 de esta API ahora devuelve 1.

ServletContext.getServerInfo()

En la implementación de la característica Servlet 3,0, esta API devuelve SMF WebContainer.

En la característica 3.1 del servlet, esta API ahora devuelve IBM WebSphere Liberty/8.5.5.<x>, donde < x> es el número de fixpack de WebSphere® Application Server .

ServletResponse.reset()

Puede utilizar ServletResponse.reset() para borrar cualquier dato de respuesta del almacenamiento intermedio y las cabeceras de respuestas cuando todavía no se ha confirmado una respuesta. Si se utiliza la característica Servlet 3.1, este método también borra cualquier registro de ServletResonse.getWriter() o ServletResponse.getOutputStream() invocado previamente.

Cabecera X-Powered-By

En la implementación de la característica Servlet 3.0, la cabecera X-Powered-By se establece en Servlet/3.0. En la implementación de la característica Servlet 3.1, la cabecera X-Powered-By se establece en Servlet/3.1.

Fusión de destinos de inyección de referencia de recursos

En la especificación Servlet 3.0, los elementos <injection-target> de una referencia de recurso definida en un archivo web-fragment.xml sólo se añaden al archivo web.xml padre si la definición de referencia de recurso de web.xml con el mismo nombre no tiene elementos <injection-target>. En la especificación Servlet 3.1, se clarifica que todos los elementos <injection-target> en descriptores web-fragment.xml se añaden a la lista de descriptores web.xml padre de los elementos <injection-target> para una referencia de recursos del mismo nombre. Si se utiliza la característica de Servlet 3.1, esta característica puede cambiar la función de aplicación existente activando destinos de inyección excluidos anteriormente del archivo web.xml.

Tolerancia de elementos duplicados en descriptores web

En la especificación Servlet 3.1, se aclaró que un archivo web.xml no puede contener dos elementos <absolute-ordering>. El despliegue de una aplicación con varios elementos <absolute-ordering> falla. Además, los descriptores web-fragment.xml no pueden contener dos elementos <ordering> . El despliegue de una aplicación con varios elementos <ordering> falla. Anteriormente, el despliegue no fallaba, pero la función de los elementos podía ser indeterminada.

Cambio de orden de fragmentos web en los casos de metadata-complete

El proceso del elemento <absolute-ordering> cambia en los casos en los que un descriptor web.xml se marca como metadata-complete="true". Anteriormente, en los casos metadata-complete="true", se utilizaban todos los archivos de fragmentos web. Cuando se utiliza la característica Servlet-3.1, el elemento <absolute-ordering> en los casos de metadata-complete se considera como completado. Este cambio provoca que los fragmentos que no aparecen en el elemento <absolute-ordering> se excluyan del proceso.

AsyncContext.dispatch()

Si la solicitud invoca AsyncContext.dispatch () sin parámetros, la solicitud se asigna al URL original. Si incluye una serie de consulta en la solicitud original y la reenvía a otro recurso utilizando una serie de consulta distinta, que invoca AsyncContext.dispatch (), los valores de parámetro de solicitud que se devuelven al recurso original cambian con el nivel de especificación. Con Servlet 3.0, la solicitud accede a los parámetros pasados en la serie de consulta de la solicitud original. Con Servlet 3.1, accede a los parámetros pasados en la serie de consulta del segundo recurso. Consulte el ejemplo siguiente:

Request for /FirstResource?param=One
First Resource:
    getParameter("param") returns "One"
           forward request to /SecondResource?param=Two
SecondResource
           getParameter(param) returns "Two"
           ac.start()
           ac.dispacth() dispatches to /FirstResource
First Resource
           Servlet-3.0 feature : getParamter("param") returns "One"
           Servlet-3.1 feature : getParameter("param") returns "Two"

This change was required by the Servlet 3.1 TCK.
La obtención del objeto de solicitud o respuesta después de un AsyncContext.dispatch () o AsyncContext.complete () no está permitido y da como resultado la siguiente excepción:
java.lang.IllegalStateException: SRVE9015E: Cannot obtain the request or response object after an AsyncContext.dispatch() or AsyncContext.complete().
    at com.ibm.ws.webcontainer31.async.AsyncContext31Impl.getRequest(AsyncContext31Impl.java:72)
    [...]

SessionCookieConfig.setComment()

Según la especificación Java™ Servlet 3.1, esta API devuelve un illegalStateException si se llama después de que ServletContext complete la inicialización, y la función Servlet 3.1 sigue este comportamiento requerido. Sin embargo, la característica 3.0 del servlet no impide el uso de esta API después de que se inicialice el contexto y, como resultado, las aplicaciones que dependen del comportamiento de la característica 3.0 del servlet no funcionarán con la característica Servlet 3.1 .

API sendRedirect(ubicación java.lang.String)

La API sendRedirect(java.lang.String location) acepta URL relativas; sin embargo, el contenedor de servlets debe convertir la URL relativa en una URL absoluta antes de poder enviar la respuesta al cliente. Si la ubicación es relativa y no incluye una barra inclinada '/' inicial, (folder/default.jsp), el contenedor la interpreta como relativa al URI de solicitud actual. Si la ubicación es relativa e incluye una barra inclinada inicial, '/', el contenedor la interpreta como relativa a la raíz del contenedor de servlet.

Por ejemplo, si la ubicación de redirección proporcionada por la aplicación es folder/default.jsp, sin el encabezado '/', y la solicitud entrante URL es http://host:port/context_root/folder o http://host:port/context_root/folder/, la solicitud se redirige a http://host:port/context_root/folder/folder/default.jsp, que es relativa a la URI de solicitud actual.

Este comportamiento se encuentra en la característica Servlet 3.0 cuando se establece la propiedad com.ibm.ws.webcontainer.redirectwithpathinfo en true. Esta propiedad se omite en la característica Servlet 3.1 y el comportamiento es el predeterminado, como se ha descrito.

Páginas de errores predeterminadas

La función ampliada de IBM® es la posibilidad de especificar una página de error predeterminada con una extensión web, como ibm-web-ext.xml.

Como función de Servlet 3.0 y posteriores, las páginas de errores predeterminadas son una modificación de la capacidad de especificar páginas de errores. Al igual que las páginas de errores normales (no predeterminadas), las páginas de errores predeterminadas se especifican en descriptores de módulo web (web.xml) y en descriptores de fragmento web (web-fragment.xml).

Las páginas de errores normales (no predeterminadas) especifican un tipo de excepción o un código de error. Una página de errores predeterminada omite tanto el tipo de excepción como el código de error. Una página de errores predeterminada se utiliza cuando un servlet lanza una excepción o establece un resultado de código de error y ninguna página de errores configurada coincide con el tipo de la excepción o con el código de error establecido.

La capacidad para definir páginas de errores predeterminadas se suministra en la especificación Servlet 3.0, y está soportada por los esquemas de Servlet 3.0. Las páginas de errores predeterminadas son páginas de errores que no contienen un elemento exception-type o error-code, según la especificación Servlet 3.1.

A continuación figuran ejemplos depáginas de errores y de páginas de errores predeterminadas.

Reglas de prioridad de página de errores predeterminada
Se aplican tres reglas para determinar la prioridad de las páginas de errores predeterminadas en los archivos web.xml, web-fragment.xml y ibm-web-ext.xml.
  • Regla 1: archivos web.xml y web-fragment.xml.

    Cuando se especifica una página de errores predeterminada en el archivo web.xml, ésta altera temporalmente (enmascara) cualquier página de errores predeterminada que se especifique en un archivo web-fragment.xml. Tampoco existe ningún error si, además, varios archivos web-fragment.xml especifican páginas de errores predeterminadas.

  • Regla 2: web-fragment.xml y web-fragment.xml.

    Si no se especifica una página de errores predeterminada en el archivo web.xml, se produce una condición de error si dos o más archivos web-fragment.xml especifican páginas de errores predeterminadas diferentes.

  • Regla 3: archivos ibm-web-ext.xml y web.xml o web-fragment.xml.

    La regla de prioridad entre el archivo ibm-web-ext.xml y los archivos web.xml o web-fragment.xml depende del nivel de característica del contenedor web.

Si el nivel de característica del contenedor web es 3.0, una página de errores predeterminada definida por un archivo ibm-web-ext.xml tiene prioridad sobre una página de errores predeterminada definida en los archivos web.xml o web-fragment.xml.
Nota: Cuando el contenedor web utiliza el nivel de característica 3.0, no puede utilizar esquemas de Servlet 3.1 . Consulte la regla sobre el uso de páginas de errores predeterminadas para los esquemas de Servlet 3.0.

Si el nivel de característica del contenedor web es 3.1 o superior, una página de errores predeterminada especificada por el archivo web.xml o web-fragment.xml tiene prioridad sobre una página de errores predeterminada especificada en el archivo ibm-web-ext.xml.

Reglas de esquema

Se aplican dos reglas al proceso de las páginas de errores predeterminadas en los archivos web.xml o web-fragment.xml. Las reglas dependen de la versión de la característica de contenedor web, qué esquema de servlet está en uso y el valor de una propiedad personalizada Java.

Estas reglas surgieron porque IBM WebSphere Application Server tradicional V8.0, no daba soporte a las páginas de error predeterminadas en el release de disponibilidad general de V8.0 . Se ha añadido soporte para las páginas de errores predeterminadas en WebSphere Application Server tradicional, en un Service Pack, mediante el APAR PM94199. Se ha añadido soporte para las páginas de errores predeterminadas en WebSphere Application Server Liberty, en un Service Pack, en el APAR PI05845. Puesto que estas actualizaciones son un cambio de la función visible externamente, la nueva función está inhabilitada de forma predeterminada y debe estar habilitada por una propiedad del sistema Java.

  • Regla 1: páginas de errores predeterminadas al utilizar el esquema de Servlet 3.0 y la versión de la característica de contenedor web 3.0.

    Cuando la versión de la característica de contenedor web es 3.0 y se especifica una página de error predeterminada en los archivos web.xml o web-fragment.xml que utilizan un esquema de Servlet 3.0 , las páginas de error predeterminadas sólo se procesan si la propiedad del sistema Java com.ibm.ws.webcontainer.allowdefaulterrorpage se establece en true. Cuando la propiedad del sistema Java no está establecida, o no está establecida en true, la página de error predeterminada se ignora. Se utiliza una página de errores predeterminada especificada por el archivo ibm-web-ext.xml.

  • Regla 2: páginas de errores predeterminadas al utilizar la versión de la característica de contenedor web 3.1.

    Cuando la versión de la característica de contenedor web es 3.1 o superior, siempre se procesa una página de error predeterminada que se especifica en el archivo web.xml o el archivo web-fragment.xml , independientemente de qué versión de esquema de servlet se utilice y de si se ha establecido la propiedad personalizada Java.

    Este caso se produce cuando un descriptor utiliza un esquema de Servlet 3.1, ya que el proceso de un descriptor que utiliza un esquema de Servlet 3.1 requiere la versión de la característica de contenedor web 3.1.

Atención: Los fragmentos web no se han añadido hasta Servlet 3.0. El archivo web-fragment.xml no tiene ningún esquema de Servlet 2.5.
Ejemplos de página de errores y de página de errores predeterminada
página de errores predeterminada que se define en un archivo ibm-web-ext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-ext xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
    version="1.0">

	<default-error-page uri="/ExtErrorPage.html"/>
</web-ext>
Elemento de página de errores error-code, que se define en el archivo web.xml o web-fragment.xml:
<error-page>
		<error-code>404</error-code>
			<location>/ErrorCodeErrorPage.html</location>
</error-page>
Elemento de página de errores exception-type, que se define en el archivo web.xml o web-fragment.xml:
<error-page>
		<exception-type>javax.servlet.ServletException</exception-type>
		<location>/ExceptionTypeErrorPage.html</location>
</error-page>
Elemento de página de errores predeterminada, que se define en el archivo web.xml o web-fragment.xml:
<error-page>
		<location>/DefaultErrorPage.html</location>
</error-page>
Ejemplos de esquema
Ejemplo de cabecera de un archivo web.xml que utiliza un esquema de Servlet 2.5:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      version="2.5">
Ejemplo de cabecera de un archivo web.xml que utiliza un esquema de Servlet 3.0:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">
Ejemplo de cabecera de un archivo web.xml que utiliza un esquema de Servlet 3.1:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
Ejemplo de cabecera de un archivo web-fragment.xml que utiliza un esquema de Servlet 3.0:
<?xml version="1.0" encoding="utf-8"?>
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
      version="3.0">
Ejemplo de cabecera de un archivo web-fragment.xml que utiliza un esquema de Servlet 3.1:
<?xml version="1.0" encoding="utf-8"?>
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
      version="3.1">