Como usar o Servlets e o Ajax?

Eu sou muito novo para aplicativos da web e Servlets e tenho a seguinte pergunta:

Sempre que imprimo algo dentro do servlet e o chama pelo webbrowser, ele retorna uma nova página contendo esse texto. Existe uma maneira de imprimir o texto na página atual usando o Ajax?

   

De fato, a palavra-chave é “ajax”: JavaScript asynchronous e XML . No entanto, nos últimos anos, é mais do que muitas vezes o Asynchronous JavaScript e o JSON . Basicamente, você permite que JS execute uma solicitação HTTP assíncrona e atualize a tree HTML DOM com base nos dados de resposta.

Como é um trabalho tedioso fazê-lo funcionar em todos os navegadores (especialmente o Internet Explorer e outros), existem muitas bibliotecas JavaScript que simplificam isso em funções únicas e abrangem o máximo de bugs / peculiaridades específicos do navegador , como jQuery , Prototype , Mootools . Desde jQuery é mais popular nos dias de hoje, eu vou usá-lo nos exemplos abaixo.

Exemplo de kickoff retornando String como texto simples

Crie um /some.jsp como abaixo (nota: o código não espera que o arquivo JSP seja colocado em uma subpasta, se você fizer isso, altere o URL do servlet de acordo):

 < !DOCTYPE html>   SO question 4112686      

Crie um servlet com um método doGet() que se pareça com isto:

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String text = "some text"; response.setContentType("text/plain"); // Set content type of the response so that jQuery knows what it can expect. response.setCharacterEncoding("UTF-8"); // You want world domination, huh? response.getWriter().write(text); // Write response body. } 

Mapeie este servlet em um padrão de URL /someservlet ou /someservlet/* como abaixo (obviamente, o padrão de URL é gratuito à sua escolha, mas você precisa alterar o URL do someservlet nos exemplos de código JS em todo o lugar de acordo):

 @WebServlet("/someservlet/*") public class SomeServlet extends HttpServlet { // ... } 

Ou, quando você ainda não estiver em um contêiner compatível com o Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc ou mais recente), mapeie-o em web.xml à moda antiga (consulte também nossa página wiki Servlets ):

  someservlet com.example.SomeServlet   someservlet /someservlet/*  

Agora abra o http: // localhost: 8080 / context / test.jsp no navegador e pressione o botão. Você verá que o conteúdo do div é atualizado com a resposta do servlet.

List retorno List como JSON

Com JSON, em vez de texto simples como formato de resposta, você pode até dar alguns passos adiante. Isso permite mais dinâmicas. Primeiro, você gostaria de ter uma ferramenta para converter entre objects Java e strings JSON. Há muitos deles também (veja a parte inferior desta página para uma visão geral). Meu favorito pessoal é o Google Gson . Faça o download e coloque seu arquivo JAR na pasta /WEB-INF/lib do seu aplicativo da web.

Aqui está um exemplo que exibe List como

. O servlet:

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List list = new ArrayList<>(); list.add("item1"); list.add("item2"); list.add("item3"); String json = new Gson().toJson(list); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); } 

O código JS:

 $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function... $.get("someservlet", function(responseJson) { // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON... var $ul = $("
    ").appendTo($("#somediv")); // Create HTML
    element and append it to HTML DOM element with ID "somediv". $.each(responseJson, function(index, item) { // Iterate over the JSON array. $("
  • ").text(item).appendTo($ul); // Create HTML
  • element, set its text content with currently iterated item and append it to the
      . }); }); });

Observe que o jQuery analisa automaticamente a resposta como JSON e fornece diretamente um object JSON ( responseJson ) como argumento de function quando você configura o tipo de conteúdo de resposta para application/json . Se você esquecer de configurá-lo ou depender de um padrão text/plain ou text/html , o argumento responseJson não fornecerá um object JSON, mas uma string simples e você precisará manipular manualmente com JSON.parse() depois, o que é totalmente desnecessário se você definir o tipo de conteúdo em primeiro lugar.

Retornando o Map como JSON

Aqui está outro exemplo que exibe Map como :

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map options = new LinkedHashMap<>(); options.put("value1", "label1"); options.put("value2", "label2"); options.put("value3", "label3"); String json = new Gson().toJson(options); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); } 

E o JSP:

 $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function... $.get("someservlet", function(responseJson) { // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON... var $select = $("#someselect"); // Locate HTML DOM element with ID "someselect". $select.find("option").remove(); // Find all child elements with tag name "option" and remove them (just to prevent duplicate options when button is pressed again). $.each(responseJson, function(key, value) { // Iterate over the JSON object. $(" 

com

  

Devolvendo List como JSON

Aqui está um exemplo que exibe List em um

onde a class Product possui as propriedades Long id , String name e BigDecimal price . O servlet:

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List products = someProductService.list(); String json = new Gson().toJson(products); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); } 

O código JS:

 $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function... $.get("someservlet", function(responseJson) { // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON... var $table = $("").appendTo($("#somediv")); // Create HTML 
element and append it to HTML DOM element with ID "somediv". $.each(responseJson, function(index, product) { // Iterate over the JSON array. $("").appendTo($table) // Create HTML element, set its text content with currently iterated item and append it to the
. .append($(". .append($(". .append($(". }); }); });
").text(product.id)) // Create HTML element, set its text content with id of currently iterated product and append it to the
").text(product.name)) // Create HTML element, set its text content with name of currently iterated product and append it to the
").text(product.price)); // Create HTML element, set its text content with price of currently iterated product and append it to the

Devolvendo List como XML

Aqui está um exemplo que efetivamente faz o mesmo que no exemplo anterior, mas com XML em vez de JSON. Ao usar o JSP como gerador de saída XML, você verá que é menos tedioso codificar a tabela e tudo. O JSTL é muito mais útil, já que você pode usá-lo para iterar os resultados e executar a formatação de dados do lado do servidor. O servlet:

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List products = someProductService.list(); request.setAttribute("products", products); request.getRequestDispatcher("/WEB-INF/xml/products.jsp").forward(request, response); } 

O código JSP (note: se você colocar o

em um , ele poderá ser reutilizado em outro lugar em uma resposta que não seja do ajax):

 < ?xml version="1.0" encoding="UTF-8"?> < %@page contentType="application/xml" pageEncoding="UTF-8"%> < %@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> < %@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>   
${product.id}

O código JS:

 $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function... $.get("someservlet", function(responseXml) { // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response XML... $("#somediv").html($(responseXml).find("data").html()); // Parse XML, find  element and append its HTML to HTML DOM element with ID "somediv". }); }); 

Você provavelmente perceberá porque o XML é muito mais poderoso do que o JSON para o propósito específico de atualizar um documento HTML usando o Ajax. JSON é engraçado, mas afinal geralmente só é útil para os chamados “serviços públicos da web”. Frameworks MVC como o JSF usam o XML sob as capas para sua magia ajax.

Ajaxifying um formulário existente

Você pode usar o jQuery $.serialize() para facilitar ajaxificação dos formulários POST existentes, sem mexer na coleta e passagem dos parâmetros de input do formulário individual. Assumindo um formulário existente que funciona perfeitamente bem sem JavaScript / jQuery (e, portanto, degrada graciosamente quando o usuário final tiver o JavaScript desabilitado):

 

Você pode melhorar progressivamente com ajax como abaixo:

 $(document).on("submit", "#someform", function(event) { var $form = $(this); $.post($form.attr("action"), $form.serialize(), function(response) { // ... }); event.preventDefault(); // Important! Prevents submitting the form. }); 

Você pode no servlet distinguir entre pedidos normais e pedidos ajax como abaixo:

 @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String foo = request.getParameter("foo"); String bar = request.getParameter("bar"); String baz = request.getParameter("baz"); boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); // ... if (ajax) { // Handle ajax (JSON or XML) response. } else { // Handle regular (JSP) response. } } 

O plugin do formulário jQuery faz menos ou mais o mesmo que o exemplo acima do jQuery, mas possui suporte transparente adicional para multipart/form-data , conforme exigido pelos uploads de arquivos.

Envio manual de parâmetros de solicitação ao servlet

Se você não tiver um formulário, mas apenas quiser interagir com o servlet “em segundo plano”, no qual deseja $.param() alguns dados, use o jQuery $.param() para converter facilmente um object JSON para uma string de consulta codificada por URL.

 var params = { foo: "fooValue", bar: "barValue", baz: "bazValue" }; $.post("someservlet", $.param(params), function(response) { // ... }); 

O mesmo método doPost() , conforme mostrado acima, pode ser reutilizado. Observe que a syntax acima também funciona com $.get() em jQuery e doGet() no servlet.

Enviando Manualmente o Objeto JSON para o Servlet

No entanto, se você pretende enviar o object JSON como um todo em vez de parâmetros de solicitação individuais por algum motivo, será necessário serializá-lo para uma string usando JSON.stringify() (não parte do jQuery) e instruir o jQuery a definir solicite o tipo de conteúdo ao application/json vez de (padrão) application/x-www-form-urlencoded . Isso não pode ser feito via function de conveniência $.post() , mas precisa ser feito via $.ajax() como abaixo.

 var data = { foo: "fooValue", bar: "barValue", baz: "bazValue" }; $.ajax({ type: "POST", url: "someservlet", contentType: "application/json", // NOT dataType! data: JSON.stringify(data), success: function(response) { // ... } }); 

Observe que muitos iniciantes misturam contentType com dataType . O contentType representa o tipo do corpo da solicitação . O dataType representa o tipo (esperado) do corpo da resposta , que geralmente é desnecessário, pois o jQuery já o autodetecta com base no header Content-Type da resposta.

Então, para processar o object JSON no servlet que não está sendo enviado como parâmetros de solicitação individuais, mas como uma string JSON inteira da maneira acima, você precisa apenas analisar manualmente o corpo da solicitação usando uma ferramenta JSON em vez de usar getParameter() o caminho normal. Ou seja, os servlets não oferecem suporte a solicitações formatadas de application/json , mas apenas pedidos formatados por application/x-www-form-urlencoded ou multipart/form-data . O Gson também suporta a análise de uma string JSON em um object JSON.

 JsonObject data = new Gson().fromJson(request.getReader(), JsonObject.class); String foo = data.get("foo").getAsString(); String bar = data.get("bar").getAsString(); String baz = data.get("baz").getAsString(); // ... 

Note que tudo isso é mais desajeitado do que apenas usar $.param() . Normalmente, você deseja usar JSON.stringify() apenas se o serviço de destino for, por exemplo, um serviço JAX-RS (RESTful) que, por algum motivo, é capaz de consumir strings JSON e não de solicitação regular.

Enviando um redirecionamento do servlet

Importante perceber e compreender é que qualquer sendRedirect() e forward() pelo servlet em uma solicitação ajax só encaminharia ou redirectia a solicitação ajax em si e não o documento principal / janela onde a solicitação ajax se originou. JavaScript / jQuery, nesse caso, apenas recuperaria a resposta redirecionada / encaminhada como variável responseText na function de retorno de chamada. Se ele representar uma página HTML inteira e não uma resposta XML ou JSON específica do ajax, tudo o que você pode fazer é replace o documento atual por ela.

 document.open(); document.write(responseText); document.close(); 

Observe que isso não altera a URL como o usuário final vê na barra de endereços do navegador. Portanto, há problemas com a possibilidade de bookmark. Portanto, é muito melhor apenas retornar uma “instrução” para JavaScript / jQuery para executar um redirecionamento em vez de retornar todo o conteúdo da página redirecionada. Por exemplo, retornando um booleano ou um URL.

 String redirectURL = "http://example.com"; Map data = new HashMap<>(); data.put("redirect", redirectURL); String json = new Gson().toJson(data); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); response.getWriter().write(json); 

 function(responseJson) { if (responseJson.redirect) { window.location = responseJson.redirect; return; } // ... } 

Veja também:

  • Chame o Servlet e invoque o código Java do JavaScript junto com os parâmetros
  • Acessar variables ​​Java / Servlet / JSP / JSTL / EL em JavaScript
  • Como alternar facilmente entre o site baseado em ajax e o site HTML básico?
  • Como fazer upload de arquivos para o servidor usando JSP / Servlet e Ajax?

O jeito certo de atualizar a página atualmente exibida no navegador do usuário (sem recarregá-la) é ter algum código em execução no navegador atualizando o DOM da página.

Esse código é tipicamente javascript que é incorporado ou vinculado a partir da página HTML, daí a sugestão AJAX. (Na verdade, se assumirmos que o texto atualizado vem do servidor por meio de uma solicitação HTTP, esse é o AJAX clássico.)

Também é possível implementar esse tipo de coisa usando algum plugin de navegador ou complemento, embora seja difícil para um plug-in acessar as estruturas de dados do navegador para atualizar o DOM. (Plugins de código nativo normalmente escrevem em algum quadro gráfico que está embutido na página.)

Eu vou te mostrar um exemplo completo de servlet e como fazer ajax call.

Aqui, vamos criar o exemplo simples para criar o formulário de login usando o servlet.

index.html

 
Name:

Password:

Aqui está ajax Sample

  $.ajax ({ type: "POST", data: 'LoginServlet='+name+'&name='+type+'&pass='+password, url: url, success:function(content) { $('#center').html(content); } }); 

Código Servlet LoginServlet: –

  package abc.servlet; import java.io.File; public class AuthenticationServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ HttpSession session = request.getSession(); String username = request.getParameter("name"); String password = request.getParameter("pass"); /// Your Code out.println("sucess / failer") } catch (Exception ex) { // System.err.println("Initial SessionFactory creation failed."); ex.printStackTrace(); System.exit(0); } } } 
 $.ajax({ type: "POST", url: "url to hit on servelet", data: JSON.stringify(json), dataType: "json", success: function(response){ // we have the response if(response.status == "SUCCESS"){ $('#info').html("Info has been added to the list successfully.
"+ "The Details are as follws :
Name : "); }else{ $('#info').html("Sorry, there is some thing wrong with the data provided."); } }, error: function(e){ alert('Error: ' + e); } });

Ajax (também AJAX), um acrônimo para Asynchronous JavaScript e XML, é um grupo de técnicas de desenvolvimento da Web inter-relacionadas usadas no lado do cliente para criar aplicativos da web asynchronouss. Com o Ajax, os aplicativos da Web podem enviar dados e recuperar dados de um servidor de forma assíncrona. Abaixo está o código de exemplo:

Função de script java da página Jsp para enviar dados ao servlet com duas variables ​​firstName e lastName:

 function onChangeSubmitCallWebServiceAJAX() { createXmlHttpRequest(); var firstName=document.getElementById("firstName").value; var lastName=document.getElementById("lastName").value; xmlHttp.open("GET","/AJAXServletCallSample/AjaxServlet?firstName=" +firstName+"&lastName="+lastName,true) xmlHttp.onreadystatechange=handleStateChange; xmlHttp.send(null); } 

Servlet para ler os dados enviados de volta para jsp no formato xml (Você também pode usar o texto. Basta alterar o conteúdo da resposta para texto e renderizar dados na function javascript).

 /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String firstName = request.getParameter("firstName"); String lastName = request.getParameter("lastName"); response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write("
"); response.getWriter().write(""+firstName+""); response.getWriter().write(""+lastName+""); response.getWriter().write("
"); }

Normalmente você não pode atualizar uma página de um servlet. Cliente (navegador) tem que solicitar uma atualização. O cliente Eiter carrega uma página totalmente nova ou solicita uma atualização para uma parte de uma página existente. Essa técnica é chamada de Ajax.

Usando o bootstrap multi select

Ajax

 function() { $.ajax({ type : "get", url : "OperatorController", data : "input=" + $('#province').val(), success : function(msg) { var arrayOfObjects = eval(msg); $("#operators").multiselect('dataprovider', arrayOfObjects); // $('#output').append(obj); }, dataType : 'text' });} } 

Em Servlet

 request.getParameter("input")