BT

Java EE 6 Web Tier: Servlets Assíncronos e maior extensibilidade

por Charles Humble , traduzido por Victor Franzonatto em 08 Fev 2010 |

Muitas das aplicações web Java são baseadas em frameworks como o Apache Wicket, Java ServerFaces, Struts ou SpringMVC. Para utilizá-los, o desenvolvedor registra seus artefatos, tais como servlets, filters e listeners no arquivo de configuração do aplicativo 'web.xml'. Isso pode resultar em um descritor complexo e também mistura o genérico XML dos frameworks com o específico da aplicação.

Um dos principais objetivos da especificação do Servlet 3.0 foi permitir a implantação de servlets, filtros e listeners, sem necessidade de recorrer à edição manual do descritor de implementação web.xml, e fornecer um meio de quebrar o arquivo web.xml em módulos distintos. Para fazer isso a especificação Servlet 3.0 acrescenta anotações como base para configuração (@WebServlet, @ServletFilter e @WebServletContextListener), tornando o arquivo web.xml opcional, e introduz um novo conceito de fragmentos da web. Esses novos conceitos já podem ser aplicados se utilizarmos algum servidor de aplicação que implemente o Java EE 6 e já são encontrados artigos, tutoriais e posts em muitos blogs.

Fragmentos da web podem ser usados para separar o "clichê" XML de configuração de frameworks do resto da configuração de um aplicativo e permitir que um aplicativo possa se auto registrar (sendo um fragmento, outro aplicativo o utiliza sem necessidade de declará-lo, pois toda configuração necessária já está dentro dele). Um fragmento da web deve ser declarado em um arquivo chamado web-fragment.xml e pode ser colocado em qualquer local no classpath de uma aplicação web, embora geralmente serão colocados no diretório META-INF do arquivo jar. O XML começa com um elemento <web-fragment> e pode conter os mesmos elementos que o descritor web.xml. Por exemplo:

<web-fragment>

	<filter>
		<filter-name>MyXSSFilter</filter-name>
		<filter-class>MyXssFilter</filter-class>
	</filter>

	<servlet>
		<servlet-name>myFrameworkServlet</servlet-name>
		<servlet-class>MyFrameworkServlet</servlet-class>
	</servlet>

	<listener>
		<listener-class>MyFrameworkListener</listener-class>
	</listener>
</web-fragment>

Os fragmentos de XML são processados pelo contêiner durante a implantação e o descritor final é montado. Uma vez que o contêiner é responsável pela montagem do arquivo web.xml, um problema pode surgir se servlets, listeners e filtros de um framework devem ser invocados em uma ordem específica. Para evitar este problema, o Servlet 3.0 API suporta tanto ordenação absoluta quanto relativa dos descritores de implantação. Você pode especificar ordenação absoluta usando o elemento <absolute-ordering> no arquivo web.xml, que funciona da seguinte forma: cada jar em WEB-INF/lib pode receber um nome em um elemento <name> dentro de um arquivo META-INF/web-fragment.xml. O arquivo WEB-INF/web.xml da aplicação pode, então, conter um elemento <absolute-ordering> que lista esses nomes dos fragmentos na ordem em que serão aplicados, em conjunto com um elemento opcional <others/> que pode ser usado para especificar se e quando jars não identificados serão incluídos. Uma vez que um desenvolvedor pode escolher uma lista de jars de confiança, pode impedir qualquer implantação acidental. Além disso, uma vez que uma ordenação pode excluir jars desnecessários que contenham o web-fragment.xml, o recurso deve otimizar o tempo de deploy. Finalmente, se você quiser evitar o auto-registro em um ambiente de produção completo, você usa o elemento <metadata-complete> no arquivo web.xml para instruir o container web para olhar para anotações, mas não fragmentos da web.

Bem como suportar os fragmentos e fazer uso de anotações como um mecanismo de configuração alternativa, Servlet 3.0 fornece a capacidade para a ligação de cópias compartilhadas de frameworks, como JAX-WS, JAX-RS e JSF, que são construídos no topo do conteiner web, usando ServletContainerInitializers. Estes são descobertos através dos serviços de jar da API e podem especificar uma lista de tipos com que trabalham. As classes dos tipos descobertos em qualquer jar contido no WEB-INF/lib são passados para o ServletContainerInitializer, que é capaz de usar as mesmas APIs de configuração programática como os ServletContextListeners.

A abordagem adotada para a construção de aplicações web mudou significativamente com o uso generalizado de solicitações HTTP em background para o servidor e tecnologias web assíncronas. Esta família de técnicas, conhecida como Ajax ou Web 2.0, tem tido um impacto significativo sobre o perfil de tráfego entre os clientes da Web (como navegadores) e servidores Web, com o cliente fazendo muito mais requisições para o servidor do que em um modelo página por página.

A situação pode ser exacerbada se um processo no servidor levar um longo tempo para concluir, como por exemplo, quando à espera de uma conexão em um pool de conexões JDBC esgotado, ou uma mensagem de uma fila JMS. Esperar na servlet é altamente ineficiente, pois é uma operação de bloqueio que consome uma thread e outros recursos limitados. Servlet 3.0 introduz a capacidade de processamento assíncrono das solicitações, assim o processo pode voltar ao container e executar outras tarefas. Quando começa o processamento assíncrono do request, outra thread pode gerar a resposta e chamar complete ou dispatch no contexto do container utilizando o método AsyncContext.dispatch.

Uma vez que um servlet assíncrono se comporta de maneira muito diferente de um não assíncrono, Servlet 3.0 requer que você especifique asyncSupported=true para indicar que o seu servlet suporta solicitações assíncronas. Você também pode marcar um servlet filter como assíncrono. O suporte para processamento assíncrono inclui novos métodos ServletRequest, como startAsync() que retorna um AsyncContext, objeto usado para encapsular os objetos request e response que foram passados na chamada. Neste ponto, a thread que serviu o request inicial está disponível para outras operações. Além disso, a API introduz uma nova classe de escuta, AsyncListener, que avisa quando uma operação assíncrona for concluída ou se um tempo limite esgotar. A classe AsyncContext inclui um método complete(), com o qual você pode consolidar um response depois que uma operação assíncrona for concluída. A classe AsyncListener tem um método dispatch() que encaminha a solicitação assíncrona para o container, para que outros frameworks, como JSP possam gerar a resposta.

Assim como introduzir uma série de novas técnicas e métodos, a especificação Servlet 3.0 apresenta uma série de aprimoramentos menores. Entre eles, o HttpServletRequest finalmente recebe suporte embutido para o multipart/form-data MIME type, a classe Cookie recebe apoio de "HttpOnly" cookies para evitar certos tipos de ataques cross-site scripting e API ServletContext foi atualizada para permitir que servlets e filters possam ser adicionados ao contexto programaticamente.

Olá visitante

Você precisa cadastrar-se no InfoQ Brasil ou para enviar comentários. Há muitas vantagens em se cadastrar.

Obtenha o máximo da experiência do InfoQ Brasil.

Dê sua opinião

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber menssagens dessa discussão
Comentários da comunidade

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber menssagens dessa discussão

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber menssagens dessa discussão

Dê sua opinião

Conteúdo educacional

Feedback geral
Bugs
Publicidade
Editorial
InfoQ Brasil e todo o seu conteúdo: todos os direitos reservados. © 2006-2013 C4Media Inc.
Política de privacidade
BT