/ / Como usar Servlets e Ajax? - java, ajax, jsp, servlets

Como usar Servlets e Ajax? - java, ajax, jsp, servlets

Sou muito novo em aplicativos da Web e Servlets e tenho a seguinte pergunta:

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

Respostas:

500 para resposta № 1

De fato, a palavra-chave é "ajax": JavaScript e XML assíncrono. No entanto, nos últimos anos, é mais do que frequentemente JavaScript assíncrono e JSON. Basicamente, você permite que o JS execute uma solicitação HTTP assíncrona e atualize a árvore DOM HTML com base nos dados da resposta.

Uma vez que é bastante tedioso trabalhar para 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 possível de bugs / peculiaridades específicos do navegador, como jQuery, Protótipo, Moools. Como o jQuery é o mais popular atualmente, vou usá-lo nos exemplos abaixo.

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

<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 4112686</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
$.get("someservlet", function(responseText) {   // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response text...
$("#somediv").text(responseText);           // Locate HTML DOM element with ID "somediv" and set its text content with the response text.
});
});
</script>
</head>
<body>
<button id="somebutton">press here</button>
<div id="somediv"></div>
</body>
</html>

Crie um servlet com um doGet() método que se parece com isso:

@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 de /someservlet ou /someservlet/* conforme abaixo (obviamente, o padrão de URL é livre para sua escolha, mas você precisa alterar o someservlet URL nos exemplos de código JS em todos os lugares de acordo):

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

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

<servlet>
<servlet-name>someservlet</servlet-name>
<servlet-class>com.example.SomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>someservlet</servlet-name>
<url-pattern>/someservlet/*</url-pattern>
</servlet-mapping>

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

Retornando List<String> como JSON

Com JSON em vez de texto simples como formato de resposta, você podeainda mais alguns passos. Permite mais dinâmica. Primeiro, você gostaria de ter uma ferramenta para converter entre objetos Java e strings JSON. Existem muitos deles também (consulte a parte inferior de esta página para uma visão geral). Meu favorito pessoal é Google Gson. Faça o download e coloque seu arquivo JAR em /WEB-INF/lib pasta do seu aplicativo da web.

Aqui está um exemplo que exibe List<String> Como <ul><li>. O servlet:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<String> 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 = $("<ul>").appendTo($("#somediv")); // Create HTML <ul> element and append it to HTML DOM element with ID "somediv".
$.each(responseJson, function(index, item) { // Iterate over the JSON array.
$("<li>").text(item).appendTo($ul);      // Create HTML <li> element, set its text content with currently iterated item and append it to the <ul>.
});
});
});

Observe que o jQuery analisa automaticamente a resposta como JSON e fornece diretamente um objeto JSON (responseJson) como argumento de função quando você define o tipo de conteúdo da resposta como application/json. Se você esquecer de configurá-lo ou confiar em um padrão de text/plain ou text/html, então o responseJson O argumento não forneceria um objeto JSON, mas uma sequência simples de baunilha e você precisaria mexer manualmente com JSON.parse() depois, o que é totalmente desnecessário se você definir o tipo de conteúdo em primeiro lugar.

Retornando Map<String, String> como JSON

Aqui está outro exemplo que exibe Map<String, String> Como <option>:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> 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.
$("<option>").val(key).text(value).appendTo($select); // Create HTML <option> element, set its value with currently iterated key and its text content with currently iterated item and finally append it to the <select>.
});
});
});

com

<select id="someselect"></select>

Retornando List<Entity> como JSON

Aqui está um exemplo que exibe List<Product> em um <table> onde o Product classe tem as propriedades Long id, String name e BigDecimal price. O servlet:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> 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 = $("<table>").appendTo($("#somediv")); // Create HTML <table> element and append it to HTML DOM element with ID "somediv".
$.each(responseJson, function(index, product) {    // Iterate over the JSON array.
$("<tr>").appendTo($table)                     // Create HTML <tr> element, set its text content with currently iterated item and append it to the <table>.
.append($("<td>").text(product.id))        // Create HTML <td> element, set its text content with id of currently iterated product and append it to the <tr>.
.append($("<td>").text(product.name))      // Create HTML <td> element, set its text content with name of currently iterated product and append it to the <tr>.
.append($("<td>").text(product.price));    // Create HTML <td> element, set its text content with price of currently iterated product and append it to the <tr>.
});
});
});

Retornando List<Entity> como XML

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

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = someProductService.list();

request.setAttribute("products", products);
request.getRequestDispatcher("/WEB-INF/xml/products.jsp").forward(request, response);
}

O código JSP (nota: se você colocar o <table> em um <jsp:include>, pode ser reutilizável em outro lugar em uma resposta não-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" %>
<data>
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td><c:out value="${product.name}" /></td>
<td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
</tr>
</c:forEach>
</table>
</data>

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 <data> element and append its HTML to HTML DOM element with ID "somediv".
});
});

Você já deve ter percebido por que o XML é tantomais poderoso que o JSON com o objetivo específico de atualizar um documento HTML usando o Ajax. O JSON é engraçado, mas, afinal, geralmente só é útil para os chamados "serviços públicos da web". Estruturas MVC como JSF use XML embaixo das cobertas para a mágica do ajax

Ajaxificando um formulário existente

Você pode usar o jQuery $.serialize() facilmente ajaxificar formulários POST existentes sembrincando e coletando e passando os parâmetros de entrada de formulário individuais. Supondo que um formulário existente funcione perfeitamente sem JavaScript / jQuery (e, portanto, seja degradado normalmente quando o usuário final estiver com o JavaScript desativado):

<form id="someform" action="someservlet" method="post">
<input type="text" name="foo" />
<input type="text" name="bar" />
<input type="text" name="baz" />
<input type="submit" name="submit" value="Submit" />
</form>

Você pode aprimorá-lo 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.
});

É possível distinguir no servlet entre solicitações normais e solicitações de ajax, conforme 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 jQuery Form faz menos ou mais o mesmo exemplo acima do jQuery, mas possui suporte transparente adicional para multipart/form-data formulários conforme exigido pelos uploads de arquivos.

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

Se você não possui um formulário, mas apenas deseja interagir com o servlet "em segundo plano", no qual deseja postar alguns dados, pode usar o jQuery $.param() converter facilmente um objeto JSON em uma string de consulta codificada em URL.

var params = {
foo: "fooValue",
bar: "barValue",
baz: "bazValue"
};

$.post("someservlet", $.param(params), function(response) {
// ...
});

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

Enviando Objeto JSON Manualmente para Servlet

Se, no entanto, você pretende enviar o objeto JSON como um todo, em vez de parâmetros de solicitação individuais, por algum motivo, será necessário serializá-lo em uma cadeia usando JSON.stringify() (não faz parte do jQuery) e instrua o jQuery para definir o tipo de conteúdo da solicitação como application/json em vez de (padrão) application/x-www-form-urlencoded. Isso não pode ser feito via $.post() função de conveniência, mas precisa ser feita 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 muitas entradas misturam contentType com dataType. o contentType representa o tipo do pedido corpo. o dataType representa o tipo (esperado) do resposta corpo, o que geralmente é desnecessário, já que o jQuery já o detecta automaticamente com base nas respostas "s Content-Type cabeçalho.

Em seguida, para processar o objeto JSON no diretórioservlet que não está sendo enviado como parâmetros de solicitação individuais, mas como uma string JSON inteira da maneira acima, você só precisa analisar manualmente o corpo da solicitação usando uma ferramenta JSON em vez de usar getParameter() da maneira usual. Ou seja, servlets não suportam application/json solicitações formatadas, mas apenas application/x-www-form-urlencoded ou multipart/form-data solicitações formatadas. O Gson também suporta a análise de uma string JSON em um objeto 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();
// ...

Observe que tudo isso é mais desajeitado do que apenas usar $.param(). Normalmente, você deseja usar JSON.stringify() somente se o serviço de destino for, p. um serviço JAX-RS (RESTful) que, por algum motivo, é capaz apenas de consumir cadeias JSON e não parâmetros de solicitação regulares.

Enviando um redirecionamento do servlet

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

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

Observe que isso não altera o URL como usuário finalvê na barra de endereços do navegador. Portanto, há problemas com a possibilidade de marcar os favoritos. Portanto, é muito melhor retornar uma "instrução" para JavaScript / jQuery 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<String, String> 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:


12 para resposta № 2

A maneira correta de atualizar a página atualmente exibida no navegador do usuário (sem recarregá-la) é fazer com que algum código em execução no navegador atualize o DOM da página.

Esse código é tipicamente javascript que éincorporado ou vinculado a partir da página HTML, daí a sugestão do AJAX. (De fato, 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 deusando algum plug-in ou complemento do navegador, embora possa ser complicado para um plug-in acessar as estruturas de dados do navegador para atualizar o DOM. (Os plug-ins de código nativo normalmente gravam em algum quadro gráfico incorporado na página.)


10 para resposta № 3

Vou mostrar um exemplo inteiro de servlet e como o ajax chama.

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

index.html

<form>
Name:<input type="text" name="username"/><br/><br/>
Password:<input type="password" name="userpass"/><br/><br/>
<input type="button" value="login"/>
</form>

Aqui está uma amostra do ajax

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

Código do 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);
}
}
}

5 para resposta № 4
$.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.<br>"+
"The  Details are as follws : <br> Name : ");

}else{
$("#info").html("Sorry, there is some thing wrong with the data provided.");
}
},
error: function(e){
alert("Error: " + e);
}
});

5 para a resposta № 5

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

Função de script java da página Jsp para enviar dados ao servlet com duas variáveis ​​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 dados enviados de volta para jsp no formato xml (você também pode usar texto. Você só precisa alterar o conteúdo da resposta para texto e renderizar dados na função 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("<details>");
response.getWriter().write("<firstName>"+firstName+"</firstName>");
response.getWriter().write("<lastName>"+lastName+"</lastName>");
response.getWriter().write("</details>");
}

3 para resposta № 6

Normalmente você não pode atualizar uma página de um servlet. O cliente (navegador) precisa 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 Ajax.


3 para resposta № 7

Usando a seleção múltipla de inicialização

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"
});}
}

No servlet

request.getParameter("input")