JSP 如何使用servlet和Ajax?

46qrfjad  于 2024-01-04  发布在  其他
关注(0)|答案(7)|浏览(260)

每当我在servlet中打印一些东西并通过web浏览器调用它时,它都会返回一个包含该文本的新页面。
我对Web应用程序和servlet非常陌生。

8oomwypt

8oomwypt1#

实际上,关键字是“Ajax”:Asynchronous JavaScript and XML。然而,近年来它更多地是 Asynchronous JavaScript and JSON。基本上,您让JavaScript执行异步HTTP请求并根据响应数据更新HTML DOM树。
由于它在所有浏览器上都是相当tedious work to make it to work的(尤其是Internet Explorer),有很多JavaScript库可以将其简化为单个函数,并尽可能多地覆盖特定于浏览器的bug/怪癖,例如jQueryPrototypeMootools

Kickoff示例以纯文本形式返回String

创建一个/some.jsp,如下所示:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>SO question 4112686</title>
  5. <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  6. <script>
  7. const yourServletURL = "${pageContext.request.contextPath}/yourServlet";
  8. $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
  9. $.get(yourServletURL, function(responseText) { // Execute Ajax GET request on your servlet URL and execute the following function with Ajax response text...
  10. $("#somediv").text(responseText); // Locate HTML DOM element with ID "somediv" and set its text content with the response text.
  11. });
  12. });
  13. </script>
  14. </head>
  15. <body>
  16. <button id="somebutton">press here</button>
  17. <div id="somediv"></div>
  18. </body>
  19. </html>

字符串
使用doGet()方法创建一个servlet,如下所示:

  1. @WebServlet("/yourServlet")
  2. public class YourServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. String text = "some text";
  6. response.setContentType("text/plain"); // Set content type of the response so that jQuery knows what it can expect.
  7. response.setCharacterEncoding("UTF-8"); // You want world domination, huh?
  8. response.getWriter().write(text); // Write response body.
  9. }
  10. }


显然,/yourServlet的URL模式可以自由选择,但是如果您更改它,则需要相应地更改yourServletURL JS变量中的/yourServlet字符串。
现在在浏览器中打开http://localhost:8080/context/test.jsp并按下按钮,您将看到div的内容使用servlet响应进行更新。

List<String>返回为JSON

使用JSON而不是纯文本作为响应格式,你甚至可以更进一步。它允许更多的动态。首先,你需要一个工具来在Java对象和JSON字符串之间进行转换。它们也有很多(参见this page的底部以获得概述)。我个人最喜欢的是Google Gson
下面是一个将List<String>显示为<ul><li>的示例。servlet:

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


JavaScript代码:

  1. $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
  2. $.get(yourServletURL, function(responseJson) { // Execute Ajax GET request on your servlet URL and execute the following function with Ajax response JSON...
  3. const $ul = $("<ul>").appendTo($("#somediv")); // Create HTML <ul> element and append it to HTML DOM element with ID "somediv".
  4. $.each(responseJson, function(index, item) { // Iterate over the JSON array.
  5. $("<li>").text(item).appendTo($ul); // Create HTML <li> element, set its text content with currently iterated item and append it to the <ul>.
  6. });
  7. });
  8. });


请注意,jQuery会自动将响应解析为JSON,并直接提供一个JSON对象(responseJson)作为函数参数。如果您忘记设置它或依赖默认值text/plaintext/html,则responseJson参数不会给予JSON对象,但是一个普通的字符串,之后您需要手动处理JSON.parse(),因此如果您首先正确设置了内容类型,那么这是完全不必要的。

Map<String, String>返回为JSON

下面是另一个将Map<String, String>显示为<option>的示例:

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


JSP:

  1. $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
  2. $.get(yourServletURL, function(responseJson) { // Execute Ajax GET request on your servlet URL and execute the following function with Ajax response JSON...
  3. const $select = $("#someselect"); // Locate HTML DOM element with ID "someselect".
  4. $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).
  5. $.each(responseJson, function(key, value) { // Iterate over the JSON object.
  6. $("<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>.
  7. });
  8. });
  9. });


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

List<Entity>返回为JSON

下面是一个在<table>中显示List<Product>的示例,其中Product类具有Long idString nameBigDecimal price属性。servlet:

  1. @Override
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. List<Product> products = someProductService.list();
  4. String json = new Gson().toJson(products);
  5. response.setContentType("application/json");
  6. response.setCharacterEncoding("UTF-8");
  7. response.getWriter().write(json);
  8. }


JS代码:

  1. $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
  2. $.get(yourServletURL, function(responseJson) { // Execute Ajax GET request on your servlet URL and execute the following function with Ajax response JSON...
  3. const $table = $("<table>").appendTo($("#somediv")); // Create HTML <table> element and append it to HTML DOM element with ID "somediv".
  4. $.each(responseJson, function(index, product) { // Iterate over the JSON array.
  5. $("<tr>").appendTo($table) // Create HTML <tr> element, set its text content with currently iterated item and append it to the <table>.
  6. .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>.
  7. .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>.
  8. .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>.
  9. });
  10. });
  11. });

以XML格式返回List<Entity>

这里有一个例子,它实际上和前面的例子一样,但是使用XML而不是JSON。当使用JSP作为XML输出生成器时,你会发现编写表格和所有内容都不那么繁琐。JSTL在这方面更有帮助,因为你可以使用它来重写结果并执行服务器端数据格式化。servlet:

  1. @Override
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. List<Product> products = someProductService.list();
  4. request.setAttribute("products", products);
  5. request.getRequestDispatcher("/WEB-INF/xml/products.jsp").forward(request, response);
  6. }


JSP代码(注意:如果您将<table>放在<jsp:include>中,则它可能在非Ajax响应中的其他地方可重用):

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <%@page contentType="application/xml" pageEncoding="UTF-8"%>
  3. <%@taglib prefix="c" uri="jakarta.tags.core" %>
  4. <%@taglib prefix="fmt" uri="jakarta.tags.fmt" %>
  5. <data>
  6. <table>
  7. <c:forEach items="${products}" var="product">
  8. <tr>
  9. <td>${product.id}</td>
  10. <td><c:out value="${product.name}" /></td>
  11. <td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
  12. </tr>
  13. </c:forEach>
  14. </table>
  15. </data>


JavaScript代码:

  1. $(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
  2. $.get(yourServletURL, function(responseXml) { // Execute Ajax GET request on your servlet URL and execute the following function with Ajax response XML...
  3. $("#somediv").html($(responseXml).find("data").html()); // Parse XML, find <data> element and append its HTML to HTML DOM element with ID "somediv".
  4. });
  5. });

现在你可能已经意识到为什么XML比JSON强大得多,尤其是在使用Ajax更新HTML文档时。JSON很有趣,但毕竟通常只对所谓的“公共Web服务”有用。像JSF这样的MVC框架使用XML隐藏其神奇的魔力。

Ajaxifying现有表单

您可以使用jQuery $.serialize()轻松地对现有的POST表单进行ajaxify,而无需在收集和传递各个表单输入参数方面进行调整。假设现有表单在没有JavaScript/jQuery的情况下工作得很好(因此当最终用户禁用JavaScript时会优雅地降级):

  1. <form id="someform" action="${pageContext.request.contextPath}/yourServletURL" method="post">
  2. <input type="text" name="foo" />
  3. <input type="text" name="bar" />
  4. <input type="text" name="baz" />
  5. <input type="submit" name="submit" value="Submit" />
  6. </form>

你可以用Ajax来逐步增强它,如下所示:

  1. $(document).on("submit", "#someform", function(event) {
  2. const $form = $(this);
  3. $.post($form.attr("action"), $form.serialize(), function(response) {
  4. // ...
  5. });
  6. event.preventDefault(); // Important! Prevents submitting the form.
  7. });

您可以在servlet中区分普通请求和Ajax请求,如下所示:

  1. @Override
  2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. String foo = request.getParameter("foo");
  4. String bar = request.getParameter("bar");
  5. String baz = request.getParameter("baz");
  6. boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
  7. // ...
  8. if (ajax) {
  9. // Handle Ajax (JSON or XML) response.
  10. } else {
  11. // Handle regular (JSP) response.
  12. }
  13. }

jQuery Form plugin与上面的jQuery示例或多或少相同,但它对文件上传所需的multipart/form-data表单提供了额外的透明支持。

手动向servlet发送请求参数

如果你根本没有表单,只是想在后台与servlet交互,从而POST一些数据,那么你可以使用jQuery $.param()轻松地将JSON对象转换为URL编码的查询字符串,按照application/x-www-form-urlencoded内容类型,就像普通HTML表单所使用的那样,这样你就可以继续使用request.getParameter(name)提取数据。

  1. const params = {
  2. foo: "fooValue",
  3. bar: "barValue",
  4. baz: "bazValue"
  5. };
  6. $.post(yourServletURL, $.param(params), function(response) {
  7. // ...
  8. });

$.post()本质上是以下$.ajax()调用的简写。

  1. $.ajax({
  2. type: "POST",
  3. url: yourServletURL,
  4. data: $.param(params),
  5. success: function(response) {
  6. // ...
  7. }
  8. });

可以重用上一节中显示的相同doPost()方法。请注意,上述$.post()语法也适用于jQuery中的$.get()和servlet中的doGet()

手动发送JSON对象到servlet

但是,如果出于某种原因,您打算将JSON对象作为一个整体而不是作为单个请求参数发送,则需要使用JSON.stringify()将其序列化为字符串(不是jQuery的一部分)并指示jQuery将请求内容类型设置为application/json而不是(默认)application/x-www-form-urlencoded。这不能通过$.post()便利函数完成,但需要通过$.ajax()完成,如下所示。

  1. const data = {
  2. foo: "fooValue",
  3. bar: "barValue",
  4. baz: "bazValue"
  5. };
  6. $.ajax({
  7. type: "POST",
  8. url: yourServletURL,
  9. contentType: "application/json", // NOT dataType!
  10. data: JSON.stringify(data),
  11. success: function(response) {
  12. // ...
  13. }
  14. });

请注意,很多初学者将contentTypedataType混合在一起。contentType表示requestbody的类型。dataType表示responsebody的(预期)类型,这通常是不必要的,因为jQuery已经根据response的Content-Type头部自动检测到它。
然后,为了处理servlet中的JSON对象(不是作为单个请求参数而是作为整个JSON字符串发送),您只需要使用JSON工具手动解析请求主体,而不是使用通常的getParameter()。也就是说,servlet不支持application/json的请求,但仅支持application/x-www-form-urlencodedmultipart/form-data的请求。Gson还支持将JSON字符串解析为JSON对象。

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

请注意,这一切都比只使用$.param()更笨拙。通常,只有当目标服务是例如JAX-RS(RESTful)服务时,您才希望使用JSON.stringify(),因为某些原因,该服务只能使用JSON字符串而不能使用常规请求参数。

从servlet发送重定向

重要的是要意识到和理解,servlet对Ajax请求的任何sendRedirect()forward()调用都只会转发或重定向 * Ajax请求本身 *,而不是Ajax请求起源的主文档/窗口。在这种情况下,JavaScript/jQuery只会检索重定向的/如果它代表整个HTML页面,而不是特定于Ajax的XML或JSON响应,那么你所能做的就是用它替换当前文档。

  1. document.open();
  2. document.write(responseText);
  3. document.close();

请注意,这并不会改变最终用户在浏览器地址栏中看到的URL。因此,书签功能存在问题。因此,最好只返回一个“指令”,让JavaScript/jQuery执行重定向,而不是返回重定向页面的全部内容。例如,通过返回布尔值或URL。

  1. String redirectURL = "http://example.com";
  2. Map<String, String> data = new HashMap<>();
  3. data.put("redirect", redirectURL);
  4. String json = new Gson().toJson(data);
  5. response.setContentType("application/json");
  6. response.setCharacterEncoding("UTF-8");
  7. response.getWriter().write(json);
  1. function(responseJson) {
  2. if (responseJson.redirect) {
  3. window.location = responseJson.redirect;
  4. return;
  5. }
  6. // ...
  7. }

参见:

展开查看全部
a7qyws3x

a7qyws3x2#

更新当前显示在用户浏览器中的页面的正确方法(无需重新加载)是让浏览器中执行的一些代码更新页面的DOM。
这些代码通常是嵌入在HTML页面中或从HTML页面链接的JavaScript,因此建议使用Ajax(实际上,如果我们假设更新的文本通过HTTP请求来自服务器,这就是经典的Ajax)。
也可以使用浏览器插件或附加组件来实现这类功能,尽管插件访问浏览器的数据结构来更新DOM可能会很棘手。(本机代码插件通常会写入嵌入在页面中的某些图形框架。)

fnatzsnv

fnatzsnv3#

我将向您展示一个servlet的完整示例以及如何进行Ajax调用。
在这里,我们将创建一个简单的示例,使用servlet创建登录表单。

文件 index.html

  1. <form>
  2. Name:<input type="text" name="username"/><br/><br/>
  3. Password:<input type="password" name="userpass"/><br/><br/>
  4. <input type="button" value="login"/>
  5. </form>

字符串

Ajax示例

  1. $.ajax
  2. ({
  3. type: "POST",
  4. data: 'LoginServlet=' + name + '&name=' + type + '&pass=' + password,
  5. url: url,
  6. success:function(content)
  7. {
  8. $('#center').html(content);
  9. }
  10. });

LoginServlet servlet代码:

  1. package abc.servlet;
  2. import java.io.File;
  3. public class AuthenticationServlet extends HttpServlet {
  4. private static final long serialVersionUID = 1L;
  5. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  6. throws ServletException, IOException
  7. {
  8. doPost(request, response);
  9. }
  10. protected void doPost(HttpServletRequest request,
  11. HttpServletResponse response)
  12. throws ServletException, IOException {
  13. try{
  14. HttpSession session = request.getSession();
  15. String username = request.getParameter("name");
  16. String password = request.getParameter("pass");
  17. /// Your Code
  18. out.println("sucess / failer")
  19. }
  20. catch (Exception ex) {
  21. // System.err.println("Initial SessionFactory creation failed.");
  22. ex.printStackTrace();
  23. System.exit(0);
  24. }
  25. }
  26. }

展开查看全部
ctehm74n

ctehm74n4#

  1. $.ajax({
  2. type: "POST",
  3. url: "URL to hit on servelet",
  4. data: JSON.stringify(json),
  5. dataType: "json",
  6. success: function(response){
  7. // We have the response
  8. if(response.status == "SUCCESS"){
  9. $('#info').html("Info has been added to the list successfully.<br>" +
  10. "The details are as follws: <br> Name: ");
  11. }
  12. else{
  13. $('#info').html("Sorry, there is some thing wrong with the data provided.");
  14. }
  15. },
  16. error: function(e){
  17. alert('Error: ' + e);
  18. }
  19. });

字符串

展开查看全部
35g0bw71

35g0bw715#

Ajax(也称为AJAX)是Asynchronous JavaScript和XML的首字母缩写,是一组相互关联的Web开发技术,用于在客户端创建异步Web应用程序。使用Ajax,Web应用程序可以异步地向服务器发送数据,并从服务器检索数据。
下面是示例代码:
一个JSP页面JavaScript函数,用于将数据提交给具有两个变量firstName和lastName的servlet:

  1. function onChangeSubmitCallWebServiceAJAX()
  2. {
  3. createXmlHttpRequest();
  4. var firstName = document.getElementById("firstName").value;
  5. var lastName = document.getElementById("lastName").value;
  6. xmlHttp.open("GET", "/AJAXServletCallSample/AjaxServlet?firstName="
  7. + firstName + "&lastName=" + lastName, true)
  8. xmlHttp.onreadystatechange = handleStateChange;
  9. xmlHttp.send(null);
  10. }

字符串
Servlet读取数据并以XML格式发送回JSP(您也可以使用文本。您只需要将响应内容更改为文本并在JavaScript函数上呈现数据。)

  1. /**
  2. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  3. */
  4. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. String firstName = request.getParameter("firstName");
  6. String lastName = request.getParameter("lastName");
  7. response.setContentType("text/xml");
  8. response.setHeader("Cache-Control", "no-cache");
  9. response.getWriter().write("<details>");
  10. response.getWriter().write("<firstName>" + firstName + "</firstName>");
  11. response.getWriter().write("<lastName>" + lastName + "</lastName>");
  12. response.getWriter().write("</details>");
  13. }

展开查看全部
lyfkaqu1

lyfkaqu16#

通常情况下,你不能从servlet更新页面。客户端(浏览器)必须请求更新。客户端要么加载一个全新的页面,要么请求更新现有页面的一部分。这种技术称为Ajax。

mf98qq94

mf98qq947#

使用Bootstrap多选择:

** AJAX **

  1. function() { $.ajax({
  2. type: "get",
  3. url: "OperatorController",
  4. data: "input=" + $('#province').val(),
  5. success: function(msg) {
  6. var arrayOfObjects = eval(msg);
  7. $("#operators").multiselect('dataprovider',
  8. arrayOfObjects);
  9. // $('#output').append(obj);
  10. },
  11. dataType: 'text'
  12. });}
  13. }

字符串

在Servlet中

  1. request.getParameter("input")

展开查看全部

相关问题