servlets

网上有很多教程,它们解释了有关使用servlet和JSP页面进行Java Web开发的一些知识,但是,我从未找到对于初学者来说足够简洁的教程。 这样的教程应该解释创建一个简单的Web应用程序的整个过程,包括前端,后端,最重要的是,人们可以用来与它们两者交互的方式 。 仅仅显示如何从服务器获取信息还不够,了解如何以结构化方式区分信息以及知道如何通过应用程序环境对后端进行更改也很重要。

我们在本文中希望实现的是,指导创建一个完整的“玩具” Web应用程序的整个过程。 从某种意义上说,它是一个“玩具”应用程序,它只做两件事,并且我们没有使用任何额外的功能来使环境变得漂亮。 该应用程序的目的很简单:

  • 添加一个带有专辑列表的乐队名称(以逗号分隔),然后按“提交”按钮将其添加到数据库中。
  • “显示乐队!” 按钮以获取乐队列表,或“显示乐队和专辑!” 按钮以获取带有其专辑的乐队列表。

该应用程序的外观是裸机越好 ,但其背后的代码是你需要开始创建自己的动态Web应用程序,这是最通常称为CRUD应用程序的一切(C reate,R EAD,U PDATE,d elete )。 之所以这样称呼它们是因为它们的所有功能都可以抽象为这些非常基本的命令。

在逐步创建应用程序之前,让我们看一下本示例中将要使用的所有工具:

  • 蚀月神
  • Java 7
  • Tomcat 7(Web应用程序服务器)
  • Gson 2.3(Google Java库)
  • jQuery 2.1.1(Javascript库)

1.前端(JSP页面)

这里没有太多要说的。 如果您已遵循其他示例,则将了解如何在Eclipse中轻松创建Dynamic Web Project ,以及如何在文件夹WebContent中创建index.jsp页面。 这将是我们应用程序的主页,并且我们将不使用任何其他页面。 当然,它总是取决于您需要创建的应用程序的类型,但是对于我们的需求而言,一页就足够了。

index.jsp

<%@ page language="java"contentType="text/html; charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Ajax - Servlets Integration Example</title><!-- Load the scripts needed for the application. --><script type="text/javascript" src="resources/jquery-2.1.1.min.js"></script><script type="text/javascript" src="resources/buttonEventsInit.js"></script><script type="text/javascript" src="resources/resultsPrinter.js"></script><script type="text/javascript" src="resources/insertBandInfo.js"></script></head><body><h1>Ajax - Servlets Integration Example</h1><p>This is an example of how to use Ajax with a servlet backend.</p></br><h3>Select a button to get the relevant information.</h3><!-- Buttons that will call the servlet to retrieve the information. --><button id="bands" type="button">Show bands!</button><button id="bands-albums" type="button">Show bands and albums!</button><!-- We need to have some empty divs in order to add the retrieved information to them. --><div id="band-results"></div></br></br><div id="bands-albums-results"></div></br></br><h3>Add the band information and press submit!</h3><h4>Band name: </h4><input type="text" id="band-name-input" value=""><br><h4>Albums: </h4><input type="text" id="album-input" value="">(Separated by commas)<br><input type="submit" id="submit-band-info" value="Submit"></body>
</html>

因此,您可以看到非常简单的东西。 我们加载所需的javascript文件,其中只有一个是外部JQuery 。 JQuery是一个众所周知的Javascript库,它功能强大 。 它使我们能够轻松获取有关页面各个元素的信息,并将事件绑定到这些元素。 在此处获取以下代码段作为简单示例:

$("#my-button").click(function() {alert("My button was clicked!");
});

此代码段的意思是:“ 单击ID为“ my-button”的元素时,我要触发一个函数,该函数会创建一个警告弹出窗口,提示“我的按钮已被单击!”。 ”。 因此,我们将执行某些操作的整个函数作为事件绑定的参数传递 。 稍后我们将解释有关JQuery的更多信息。 您可以在此处下载JQuery 。

这里有一些事情要考虑:

  • 我们已为将要使用的所有重要元素指定了ID。 因此, 按钮输入框和空的<div>元素都有唯一的ID。
  • 我们创建了2个空的<div>元素,其中将包含结果。 如果您需要一个用于存放东西的容器 ,并且需要将该容器始终放置在特定位置 ,那么通常会遵循此设计模式。 这样,我们就无需检查信息的放置位置,因为页面中为此保留了一个位置。 同样,第二个div(带有专辑的乐队)将始终位于第一个div(仅乐队名称)之下。 当我们按下仅乐队信息的按钮时,它将被添加到带有专辑的乐队顶部。

2.向服务器询问数据(前端和后端)

2.1从前端使用Ajax发出GET请求。

因此,我们需要做的第一件事就是找到一种方法来询问服务器所需的数据,在本例中为乐队名称或乐队和专辑。 我们已经在各自的按钮上添加了两个ID( “乐队”“乐队和专辑” ),因此我们需要将事件绑定到这些 ID ,以便每次按下按钮时都可以调用服务器 。 为此,我们将使用一些Javascript,包含在buttonEventsInit.js文件中。

注意:每个Javascipt文件都保存在目录WebContent / resources下,以便授予访问浏览器的权限。

buttonEventsInit.js

// When the page is fully loaded...
$(document).ready(function() {// Add an event that triggers when ANY button// on the page is clicked...$("button").click(function(event) {// Get the button id, as we will pass it to the servlet// using a GET request and it will be used to get different// results (bands OR bands and albums).var buttonID = event.target.id;// Basic JQuery Ajax GET request. We need to pass 3 arguments://       1. The servlet url that we will make the request to.//      2. The GET data (in our case just the button ID).//     3. A function that will be triggered as soon as the request is successful.// Optionally, you can also chain a method that will handle the possibility// of a failed request.$.get('DBRetrievalServlet', {"button-id": buttonID},function(resp) { // on sucess// We need 2 methods here due to the different ways of // handling a JSON object.if (buttonID === "bands")printBands(resp);else if (buttonID === "bands-albums")printBandsAndAlbums(resp); }).fail(function() { // on failurealert("Request failed.");});});
});

让我们解释一下这里发生的情况。 页面加载后 (我们这样做是为了确保所有元素都就位),我们将click事件绑定到页面中的每个按钮元素。 从现在开始, 每单击一个按钮 ,GET请求就会发送到服务器,其中包含按下了哪个按钮的信息。 服务器将发送回正确的响应(以JSON对象的形式,稍后我们将对此进行说明),并且我们将根据所按下的按钮对该对象执行不同的操作(因为每个按钮将接收结构不同的 JSON)目的)。

查看上面示例中有关向服务器发出GET请求的正确方法的注释。 您将需要提供URL(也可以是servlet的URL),数据和将要触发的功能,并具有服务器响应(JSON对象)作为参数

2.2处理请求并将数据发送回客户端。

那么,当我们发出请求时服务器将如何处理? 我们在这里使用了许多类,因此请再次记住我们正在构建的应用程序将包含两种目录:乐队和带有专辑的乐队。 因此,我们正在使用:

  • MusicDatabase.java:使用Singleton模式以提供一个持久对象的类,该对象将包含需要发送回客户端的信息。
  • DBRetrievalServlet.java:将用于处理GET请求和使用其他类的servlet, 提供带有查询信息的响应
  • BandWithAlbums.java:一个用于创建新的“数据保存对象”的类 ,在我们的例子中,该类包含乐队名称和专辑列表。

因此,让我们检查这些类中的每一个并解释它们的用法。

DBRetrievalServlet.java

package servlets;
import informationClasses.MusicDatabase;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/DBRetrievalServlet")
public class DBRetrievalServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// We set a specific return type and encoding// in order to take advantage of the browser capabilities.response.setContentType("application/json");response.setCharacterEncoding("UTF-8");// Depending on the GET parameters, passed from the Ajax call,// we are able to differentiate the requests and call the appropriate// method. We can always use more classes for more use-cases.// The response object returns the information (as a JSON object in String form)// to the browser.String buttonID = request.getParameter("button-id");switch (buttonID) {case "bands":response.getWriter().write(MusicDatabase.getInstance().getBands());break;case "bands-albums":response.getWriter().write(MusicDatabase.getInstance().getBandsAndAlbums());break;}}
}

我们获得参数“ button-id” ,该参数包含在客户端发送的信息中(在请求对象中),根据所按下的按钮的种类,我们需要通过调用MusicDatabase实例来获得不同类型的信息。并每次调用不同的方法。

注意:单例模式

关于MusicDatabase实例…我们使用的是Singleton模式 ,这意味着因为我们只希望有1个类的实例,所以我们不会通过自己调用new关键字来创建新实例。 相反,我们从MusicDatabase类本身调用一个方法,并要求一个实例。

  1. 如果尚未创建该实例,我们将创建一个实例并将其返回。
  2. 如果已创建,则返回现有实例。

无法从外部访问构造函数 ,也无法意外创建另一个实例。 您可以在线找到有关Singleton模式的更多信息。

MusicDatabase.java

package informationClasses;import java.util.ArrayList;
import java.util.List;import jsonObjects.BandWithAlbums;import com.google.gson.Gson;public class MusicDatabase {private List bandNames;private List bandsAndAlbums;// Singleton methodsprivate static MusicDatabase dbInstance = null;protected MusicDatabase() {bandNames = new ArrayList<>();bandsAndAlbums = new ArrayList<>();}public static MusicDatabase getInstance() {if(dbInstance == null) {dbInstance = new MusicDatabase();}return dbInstance;}public void setBandAndAlbums(String bandName, ArrayList bandAlbums) {bandNames.add(bandName);bandsAndAlbums.add(new BandWithAlbums(bandName, bandAlbums));}public String getBands() {return new Gson().toJson(bandNames);}public String getBandsAndAlbums() {return new Gson().toJson(bandsAndAlbums);}
}

我们将在这里检查的方法是getBands()getBandsAndAlbums() 。 我们只需要这两种方法,它们就非常简单,因为这里有些东西可以帮助我们:

  • Gson是Google的Java库,它使我们能够从Java对象轻松创建JSON对象。 该对象可以是任何东西,从简单的数据结构到包含信息,其他数据结构等的对象。在我们的例子中,我们有2个这样的数据结构:

    • A List<String> bandNames ,它仅包含A List<String> bandNames形式的乐队名称。
  • BandWithAlbums类 ,使我们能够保存有关乐队的更多信息。 它是一个数据保存类,其中包含乐队名称( String和乐队List<String> 。 通过返回此对象,您还将返回所有关联的信息。

总而言之,使用命令new Gson().toJson(Object obj)的Gson库可以将大多数对象和数据结构转换为JSON格式,浏览器可以通过Javascript轻松使用。

注意:您需要将Gson库添加到类路径中才能起作用。

BandWithAlbums.java

package jsonObjects;import java.util.ArrayList;public class BandWithAlbums {String bandName;ArrayList bandAlbums;public BandWithAlbums(String bandName, ArrayList bandAlbums) {this.bandName = bandName;this.bandAlbums = bandAlbums;}
}

正如我们之前已经说过的,这是一个简单的数据保存类。 从某种意义上说,它包含乐队的名称和专辑,代表“乐队”。

2.3将数据呈现给浏览器。

因此,一旦有了所需的数据,就可以在文件buttonEventsInit.js中看到,我们可以选择调用两种不同的方法,具体取决于进行调用的按钮的ID。 我们将展示这两种方法的作用,以及如何将数据展示给浏览器

resultsPrinter.js

// Both those functions get a json object as an argument,
// which itself also holds other objects.// 1. The first function is supposed to get an object
//  containing just a list of band names.
// 2. The second function is supposed to get an object containing
//  bands with albums, which essentially means a list of objects
//  which hold (1) a band name and (2) a list of albums.function printBands(json) {// First empty the <div> completely and add a title.$("#band-results").empty().append("<h3>Band Names</h3>");// Then add every band name contained in the list.    $.each(json, function(i, name) {$("#band-results").append(i + 1, ". " + name + " </br>");});
};function printBandsAndAlbums(json) {// First empty the <div> completely and add a title.$("#bands-albums-results").empty().append("<h3>Band Names and Albums</h3>");// Get each band object...$.each(json, function(i, bandObject) {// Add to the <div> every band name...$("#bands-albums-results").append(i + 1, ". " + bandObject.bandName + " </br>");// And then for every band add a list of their albums.$.each(bandObject.bandAlbums, function(i, album) {$("#bands-albums-results").append("--" + album + "</br>");});});
};

为了了解这些功能如何工作,我们必须看一下服务器返回给客户端的响应对象。 在第一种情况下,我们期望仅列出乐队名称,因此期望的对象将只是列表:

["The Beatles", "Metallica"]

另一方面,在第二种情况下,我们希望接收全波段信息,在这种情况下,json对象将如下所示:

[{bandName: "The Beatles",bandAlbums: ["White Album", "Let it be"]},{bandName: "Metallica",bandAlbums: ["St Anger", "The Black Album"]}
]

因此,我们需要两种不同的方式处理请求。 但是,在每种情况下,我们将要使用的div empty() ,并使用一些非常方便的JQuery函数添加从服务器获取的信息。

这样,我们的应用程序的第一部分就完成了。 查看屏幕快照以查看结果。

结果显示在浏览器中。

3.从用户输入(前端和后端)更新服务器

3.1使用Ajax发出POST请求。

在这一部分中,我们将研究如何将数据发送到服务器 。 在本教程的上半部分,我们已经通过处理GET请求获得了工作方式的提示,并且这里的步骤实际上并没有什么不同,唯一的例外是允许用户为应用程序提供输入 。 让我们看一下我们正在使用的代码以及每个文件的功能。

insertBandInfo.js

$(document).ready(function() {// Add an event that triggers when the submit// button is pressed.$("#submit-band-info").click(function() {// Get the text from the two inputs.var bandName = $("#band-name-input").val();var albumName = $("#album-input").val();// Fail if one of the two inputs is empty, as we need// both a band name and albums to make an insertion.if (bandName === "" || albumName === "") {alert("Not enough information for an insertion!");return;}// Ajax POST request, similar to the GET request.$.post('DBInsertionServlet',{"bandName": bandName, "albumName": albumName},function() { // on successalert("Insertion successful!");}).fail(function() { //on failurealert("Insertion failed.");});});
});

如果您遵循了教程的上一部分,那么很容易理解我们在这里所做的事情。 另一个单击事件,现在仅针对“ 提交”按钮的特定ID,在检查了两个输入框是否确实有输入之后,该事件会发出POST请求(向为此目的专门使用的新Servlet)发送数据我们想要的(乐队名称和专辑列表)。

3.2将用户输入保存在我们的“数据库”中。

DBInsertionServlet.java

package servlets;import informationClasses.MusicDatabase;import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/DBInsertionServlet")
public class DBInsertionServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Map<String, String[]> bandInfo = request.getParameterMap();// In this case here we are not using the data sent to just do different things.// Instead we are using them as information to make changes to the server,// in this case, adding more bands and albums.String bandName = Arrays.asList(bandInfo.get("bandName")).get(0);String albums = Arrays.asList(bandInfo.get("albumName")).get(0);MusicDatabase.getInstance().setBandAndAlbums(bandName, getAlbumNamesFromString(albums)); // return successresponse.setStatus(200); }// Split the album String in order to get a list of albums.private ArrayList getAlbumNamesFromString(String albums) {return new ArrayList(Arrays.asList(albums.split(",")));}
}

当servlet收到请求时,它将从请求映射中提取bandName,并包含一个包含唱片集名称的String当找到逗号时,我们通过String分成多个部分来创建专辑列表。 最后,我们调用MusicDatabase实例,在该实例中添加乐队名称和专辑列表,如果您从以前检查一下类定义,则可以看到:

  • 我们将乐队名称添加到bandNames列表中。
  • 我们创建一个新的Band对象(使用名称和专辑列表),并将其添加到bandsWithalbums列表中。

此后,该servlet完成,并将成功状态响应发送回客户端。 我们已将所有内容添加到列表中,并且可以随时按JSON格式发送。 举例来说,让我们看看如果我自己添加一个新乐队会发生什么。

添加新乐队。

这个新乐队已经在我的“数据库”中,并要求再次查看该信息后,它就在那里!

4.下载项目

这是Ajax – Servlets集成的示例。 我想想我可以帮助您全面了解如何实现Web应用程序的每个部分(前端-后端),以及将各个部分连接在一起以创建允许用户在其上进行输入和更改的软件的最简单方法。服务器以及客户端!

您可以在此处下载此示例的完整源代码: AjaxServletsIntegration

翻译自: https://www.javacodegeeks.com/2014/09/jquery-ajax-servlets-integration-building-a-complete-application.html

servlets

servlets_jQuery Ajax – Servlets集成:构建完整的应用程序相关推荐

  1. jQuery Ajax – Servlets集成:构建完整的应用程序

    网上有很多教程,它们解释了有关使用servlet和JSP页面进行Java Web开发的一些知识,但是,我从来没有找到对于初学者来说足够简洁,简单的教程. 这样的教程应该解释创建一个简单的Web应用程序 ...

  2. 【小程序云开发】不用后端也能构建完整的微信小程序

    文章目录 什么是微信小程序云函数 云数据库 HTTP 云函数 定时触发云函数 总结 写在最后 什么是微信小程序云函数 微信小程序云函数是通过微信小程序云开发提供的一种服务器端代码,用于在小程序中进行服 ...

  3. 【集成学习-组队学习】2.使用sklearn构建完整的机器学习项目流程

    使用sklearn构建完整的机器学习项目流程 组队学习来源: Datewhle23期__集成学习(上) : https://github.com/datawhalechina/team-learnin ...

  4. 20210317_23期_集成学习(上)_Task02_sklearn构建完整机器学习模型

    二.Sklearn构建完整机器学习模型 目录 二.Sklearn构建完整机器学习模型 来源 2.1 机器学习项目通常步骤 2.2 用Sklearn对机器学习项目的构建 2.2.1 导入数据集及特征选择 ...

  5. Unity提出ProtoRes模型:稀疏可变的输入也能构建完整人体姿态

    清华大数据软件团队官方微信公众号来源:机器之心 本文约2400字,建议阅读7分钟 稀疏约束通常会引起姿态参数的扰动,其背后的主要原因是缺乏归纳偏置来解决从一小组约束中恢复完整姿势的不适定问题. 人体姿 ...

  6. ROS探索总结(十六)(十七)(十八)(十九)——HRMRP机器人的设计 构建完整的机器人应用系统 重读tf 如何配置机器人的导航功能

    ROS探索总结(十六)--HRMRP机器人的设计 1. HRMRP简介         HRMRP(Hybrid Real-time Mobile Robot Platform,混合实时移动机器人平台 ...

  7. CI/CD(持续集成构建/持续交付):如何测试/集成/交付项目代码?(Jenkins,TravisCI)

    Table of Contents CI(Continuous integration,持续集成) CD(Continuous Delivery, 持续交付) Different types of t ...

  8. 基于 Node.js + Koa 构建完整的 Web API (配置 ESLint 和使用 Airbnb 编码规范)

    主题内容:基于 Node.js + Koa 构建完整的 Web API (配置 ESLint 和使用 Airbnb 代码规范) 背景描述:上一篇 基于 Node.js + Koa 构建完整的 Web ...

  9. 软件开发管理工具--持续集成构建

    持续集成概述 什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题.尤其是近些年来,敏捷(Agile) 在软件工程领域 ...

最新文章

  1. 机器学习数据预处理之缺失值:固定值填充
  2. 哈尔滨理工大学ACM集训第二周总结
  3. 涉及的一些操作的命令
  4. 方差和协方差的数据意义
  5. Python与机器视觉(x)下雨啦,图片模拟雨天效果
  6. Effective C# Item33:限制类型的可见性
  7. c语言计算日期天数,关于计算两个日期间天数的代码,大家来看看
  8. java rsa 128_如何用java实现128位密钥的RSA算法
  9. 分享开发HTML5手机游戏的5个注意要点
  10. 搭建DNS服务,正向解析域名
  11. kinect 2.0 SDK-深度图与彩色图对齐
  12. MySQL 日期时间加减
  13. Matlab实现一元线性拟合
  14. 往事如烟 - 老钟14
  15. 淘宝客搜索链接组成详解
  16. python计算圆周率_Python圆周率计算
  17. 访谈完100个年入百万的自媒体人后,我总结了出了他们的共性
  18. 喝咖啡写脚本,顺便再加一点点CSS语法糖 1.选择环境
  19. 【HTML】网页开发的一些单词(关键词),新手必备。
  20. Excel每页都打印表头

热门文章

  1. nssl1256-C(盟主的忧虑)【并查集】
  2. 5、mysql中的库操作
  3. js Date 函数方法
  4. JAVA面试常考系列十
  5. Spring Boot Server容器配置
  6. 一篇文章搞定面试中的二叉树
  7. 2018蓝桥杯省赛---java---A---7(三体攻击)
  8. 给数据表中的字段添加约束
  9. 检测性异常VS非检测性异常
  10. Android增加自定义监听事件