servlets_jQuery Ajax – Servlets集成:构建完整的应用程序
servlets
網(wǎng)上有很多教程,它們解釋了有關(guān)使用servlet和JSP頁面進(jìn)行Java Web開發(fā)的一些知識(shí),但是,我從未找到對(duì)于初學(xué)者來說足夠簡(jiǎn)潔的教程。 這樣的教程應(yīng)該解釋創(chuàng)建一個(gè)簡(jiǎn)單的Web應(yīng)用程序的整個(gè)過程,包括前端,后端,最重要的是,人們可以用來與它們兩者交互的方式 。 僅僅顯示如何從服務(wù)器獲取信息還不夠,了解如何以結(jié)構(gòu)化方式區(qū)分信息以及知道如何通過應(yīng)用程序環(huán)境對(duì)后端進(jìn)行更改也很重要。
我們?cè)诒疚闹邢M麑?shí)現(xiàn)的是,指導(dǎo)創(chuàng)建一個(gè)完整的“玩具” Web應(yīng)用程序的整個(gè)過程。 從某種意義上說,它是一個(gè)“玩具”應(yīng)用程序,它只做兩件事,并且我們沒有使用任何額外的功能來使環(huán)境變得漂亮。 該應(yīng)用程序的目的很簡(jiǎn)單:
- 添加一個(gè)帶有專輯列表的樂隊(duì)名稱(以逗號(hào)分隔),然后按“提交”按鈕將其添加到數(shù)據(jù)庫中。
- 按“顯示樂隊(duì)!” 按鈕以獲取樂隊(duì)列表,或“顯示樂隊(duì)和專輯!” 按鈕以獲取帶有其專輯的樂隊(duì)列表。
該應(yīng)用程序的外觀是裸機(jī)越好 ,但其背后的代碼是你需要開始創(chuàng)建自己的動(dòng)態(tài)Web應(yīng)用程序,這是最通常稱為CRUD應(yīng)用程序的一切(C reate,R EAD,U PDATE,d elete )。 之所以這樣稱呼它們是因?yàn)樗鼈兊乃泄δ芏伎梢猿橄鬄檫@些非常基本的命令。
在逐步創(chuàng)建應(yīng)用程序之前,讓我們看一下本示例中將要使用的所有工具:
- 蝕月神
- Java 7
- Tomcat 7(Web應(yīng)用程序服務(wù)器)
- Gson 2.3(Google Java庫)
- jQuery 2.1.1(Javascript庫)
1.前端(JSP頁面)
這里沒有太多要說的。 如果您已遵循其他示例,則將了解如何在Eclipse中輕松創(chuàng)建Dynamic Web Project ,以及如何在文件夾WebContent中創(chuàng)建index.jsp頁面。 這將是我們應(yīng)用程序的主頁,并且我們將不使用任何其他頁面。 當(dāng)然,它總是取決于您需要?jiǎng)?chuàng)建的應(yīng)用程序的類型,但是對(duì)于我們的需求而言,一頁就足夠了。
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>因此,您可以看到非常簡(jiǎn)單的東西。 我們加載所需的javascript文件,其中只有一個(gè)是外部JQuery 。 JQuery是一個(gè)眾所周知的Javascript庫,它功能強(qiáng)大 。 它使我們能夠輕松獲取有關(guān)頁面各個(gè)元素的信息,并將事件綁定到這些元素。 在此處獲取以下代碼段作為簡(jiǎn)單示例:
$("#my-button").click(function() {alert("My button was clicked!"); });此代碼段的意思是:“ 單擊ID為“ my-button”的元素時(shí),我要觸發(fā)一個(gè)函數(shù),該函數(shù)會(huì)創(chuàng)建一個(gè)警告彈出窗口,提示“我的按鈕已被單擊!”。 ”。 因此,我們將執(zhí)行某些操作的整個(gè)函數(shù)作為事件綁定的參數(shù)傳遞 。 稍后我們將解釋有關(guān)JQuery的更多信息。 您可以在此處下載JQuery 。
這里有一些事情要考慮:
- 我們已為將要使用的所有重要元素指定了ID。 因此, 按鈕 , 輸入框和空的<div>元素都有唯一的ID。
- 我們創(chuàng)建了2個(gè)空的<div>元素,其中將包含結(jié)果。 如果您需要一個(gè)用于存放東西的容器 ,并且需要將該容器始終放置在特定位置 ,那么通常會(huì)遵循此設(shè)計(jì)模式。 這樣,我們就無需檢查信息的放置位置,因?yàn)轫撁嬷袨榇吮A袅艘粋€(gè)位置。 同樣,第二個(gè)div(帶有專輯的樂隊(duì))將始終位于第一個(gè)div(僅樂隊(duì)名稱)之下。 當(dāng)我們按下僅樂隊(duì)信息的按鈕時(shí),它將被添加到帶有專輯的樂隊(duì)頂部。
2.向服務(wù)器詢問數(shù)據(jù)(前端和后端)
2.1從前端使用Ajax發(fā)出GET請(qǐng)求。
因此,我們需要做的第一件事就是找到一種方法來詢問服務(wù)器所需的數(shù)據(jù),在本例中為樂隊(duì)名稱或樂隊(duì)和專輯。 我們已經(jīng)在各自的按鈕上添加了兩個(gè)ID( “樂隊(duì)”和“樂隊(duì)和專輯” ),因此我們需要將事件綁定到這些 ID ,以便每次按下按鈕時(shí)都可以調(diào)用服務(wù)器 。 為此,我們將使用一些Javascript,包含在buttonEventsInit.js文件中。
注意:每個(gè)Javascipt文件都保存在目錄WebContent / resources下,以便授予訪問瀏覽器的權(quán)限。
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.");});}); });讓我們解釋一下這里發(fā)生的情況。 頁面加載后 (我們這樣做是為了確保所有元素都就位),我們將click事件綁定到頁面中的每個(gè)按鈕元素。 從現(xiàn)在開始, 每單擊一個(gè)按鈕 ,GET請(qǐng)求就會(huì)發(fā)送到服務(wù)器,其中包含按下了哪個(gè)按鈕的信息。 服務(wù)器將發(fā)送回正確的響應(yīng)(以JSON對(duì)象的形式,稍后我們將對(duì)此進(jìn)行說明),并且我們將根據(jù)所按下的按鈕對(duì)該對(duì)象執(zhí)行不同的操作(因?yàn)槊總€(gè)按鈕將接收結(jié)構(gòu)不同的 JSON)目的)。
查看上面示例中有關(guān)向服務(wù)器發(fā)出GET請(qǐng)求的正確方法的注釋。 您將需要提供URL(也可以是servlet的URL),數(shù)據(jù)和將要觸發(fā)的功能,并具有服務(wù)器響應(yīng)(JSON對(duì)象)作為參數(shù) 。
2.2處理請(qǐng)求并將數(shù)據(jù)發(fā)送回客戶端。
那么,當(dāng)我們發(fā)出請(qǐng)求時(shí)服務(wù)器將如何處理? 我們?cè)谶@里使用了許多類,因此請(qǐng)?jiān)俅斡涀∥覀冋跇?gòu)建的應(yīng)用程序?qū)瑑煞N目錄:樂隊(duì)和帶有專輯的樂隊(duì)。 因此,我們正在使用:
- MusicDatabase.java:使用Singleton模式以提供一個(gè)持久對(duì)象的類,該對(duì)象將包含需要發(fā)送回客戶端的信息。
- DBRetrievalServlet.java:將用于處理GET請(qǐng)求和使用其他類的servlet, 提供帶有查詢信息的響應(yīng) 。
- BandWithAlbums.java:一個(gè)用于創(chuàng)建新的“數(shù)據(jù)保存對(duì)象”的類 ,在我們的例子中,該類包含樂隊(duì)名稱和專輯列表。
因此,讓我們檢查這些類中的每一個(gè)并解釋它們的用法。
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;}} }我們獲得參數(shù)“ button-id” ,該參數(shù)包含在客戶端發(fā)送的信息中(在請(qǐng)求對(duì)象中),根據(jù)所按下的按鈕的種類,我們需要通過調(diào)用MusicDatabase實(shí)例來獲得不同類型的信息。并每次調(diào)用不同的方法。
注意:單例模式
關(guān)于MusicDatabase實(shí)例…我們使用的是Singleton模式 ,這意味著因?yàn)槲覀冎幌M?個(gè)類的實(shí)例,所以我們不會(huì)通過自己調(diào)用new關(guān)鍵字來創(chuàng)建新實(shí)例。 相反,我們從MusicDatabase類本身調(diào)用一個(gè)方法,并要求一個(gè)實(shí)例。
無法從外部訪問構(gòu)造函數(shù) ,也無法意外創(chuàng)建另一個(gè)實(shí)例。 您可以在線找到有關(guān)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() 。 我們只需要這兩種方法,它們就非常簡(jiǎn)單,因?yàn)檫@里有些東西可以幫助我們:
- Gson是Google的Java庫,它使我們能夠從Java對(duì)象輕松創(chuàng)建JSON對(duì)象。 該對(duì)象可以是任何東西,從簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)到包含信息,其他數(shù)據(jù)結(jié)構(gòu)等的對(duì)象。在我們的例子中,我們有2個(gè)這樣的數(shù)據(jù)結(jié)構(gòu):
- A List<String> bandNames ,它僅包含A List<String> bandNames形式的樂隊(duì)名稱。
- BandWithAlbums類 ,使我們能夠保存有關(guān)樂隊(duì)的更多信息。 它是一個(gè)數(shù)據(jù)保存類,其中包含樂隊(duì)名稱( String和樂隊(duì)List<String> 。 通過返回此對(duì)象,您還將返回所有關(guān)聯(lián)的信息。
總而言之,使用命令new Gson().toJson(Object obj)的Gson庫可以將大多數(shù)對(duì)象和數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為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;} }正如我們之前已經(jīng)說過的,這是一個(gè)簡(jiǎn)單的數(shù)據(jù)保存類。 從某種意義上說,它包含樂隊(duì)的名稱和專輯,代表“樂隊(duì)”。
2.3將數(shù)據(jù)呈現(xiàn)給瀏覽器。
因此,一旦有了所需的數(shù)據(jù),就可以在文件buttonEventsInit.js中看到,我們可以選擇調(diào)用兩種不同的方法,具體取決于進(jìn)行調(diào)用的按鈕的ID。 我們將展示這兩種方法的作用,以及如何將數(shù)據(jù)展示給瀏覽器 。
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>");});}); };為了了解這些功能如何工作,我們必須看一下服務(wù)器返回給客戶端的響應(yīng)對(duì)象。 在第一種情況下,我們期望僅列出樂隊(duì)名稱,因此期望的對(duì)象將只是列表:
["The Beatles", "Metallica"]另一方面,在第二種情況下,我們希望接收全波段信息,在這種情況下,json對(duì)象將如下所示:
[{bandName: "The Beatles",bandAlbums: ["White Album", "Let it be"]},{bandName: "Metallica",bandAlbums: ["St Anger", "The Black Album"]} ]因此,我們需要兩種不同的方式處理請(qǐng)求。 但是,在每種情況下,我們將要使用的div empty() ,并使用一些非常方便的JQuery函數(shù)添加從服務(wù)器獲取的信息。
這樣,我們的應(yīng)用程序的第一部分就完成了。 查看屏幕快照以查看結(jié)果。
結(jié)果顯示在瀏覽器中。
3.從用戶輸入(前端和后端)更新服務(wù)器
3.1使用Ajax發(fā)出POST請(qǐng)求。
在這一部分中,我們將研究如何將數(shù)據(jù)發(fā)送到服務(wù)器 。 在本教程的上半部分,我們已經(jīng)通過處理GET請(qǐng)求獲得了工作方式的提示,并且這里的步驟實(shí)際上并沒有什么不同,唯一的例外是允許用戶為應(yīng)用程序提供輸入 。 讓我們看一下我們正在使用的代碼以及每個(gè)文件的功能。
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.");});}); });如果您遵循了教程的上一部分,那么很容易理解我們?cè)谶@里所做的事情。 另一個(gè)單擊事件,現(xiàn)在僅針對(duì)“ 提交”按鈕的特定ID,在檢查了兩個(gè)輸入框是否確實(shí)有輸入之后,該事件會(huì)發(fā)出POST請(qǐng)求(向?yàn)榇四康膶iT使用的新Servlet)發(fā)送數(shù)據(jù)我們想要的(樂隊(duì)名稱和專輯列表)。
3.2將用戶輸入保存在我們的“數(shù)據(jù)庫”中。
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(",")));} }當(dāng)servlet收到請(qǐng)求時(shí),它將從請(qǐng)求映射中提取bandName,并包含一個(gè)包含唱片集名稱的String 。 當(dāng)找到逗號(hào)時(shí),我們通過將String分成多個(gè)部分來創(chuàng)建專輯列表。 最后,我們調(diào)用MusicDatabase實(shí)例,在該實(shí)例中添加樂隊(duì)名稱和專輯列表,如果您從以前檢查一下類定義,則可以看到:
- 我們將樂隊(duì)名稱添加到bandNames列表中。
- 我們創(chuàng)建一個(gè)新的Band對(duì)象(使用名稱和專輯列表),并將其添加到bandsWithalbums列表中。
此后,該servlet完成,并將成功狀態(tài)響應(yīng)發(fā)送回客戶端。 我們已將所有內(nèi)容添加到列表中,并且可以隨時(shí)按JSON格式發(fā)送。 舉例來說,讓我們看看如果我自己添加一個(gè)新樂隊(duì)會(huì)發(fā)生什么。
添加新樂隊(duì)。
這個(gè)新樂隊(duì)已經(jīng)在我的“數(shù)據(jù)庫”中,并要求再次查看該信息后,它就在那里!
4.下載項(xiàng)目
這是Ajax – Servlets集成的示例。 我想想我可以幫助您全面了解如何實(shí)現(xiàn)Web應(yīng)用程序的每個(gè)部分(前端-后端),以及將各個(gè)部分連接在一起以創(chuàng)建允許用戶在其上進(jìn)行輸入和更改的軟件的最簡(jiǎn)單方法。服務(wù)器以及客戶端!
您可以在此處下載此示例的完整源代碼: AjaxServletsIntegration
翻譯自: https://www.javacodegeeks.com/2014/09/jquery-ajax-servlets-integration-building-a-complete-application.html
servlets
總結(jié)
以上是生活随笔為你收集整理的servlets_jQuery Ajax – Servlets集成:构建完整的应用程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 任正非称从来没有说“打倒美国
- 下一篇: 改善“GTA+ 订阅量”,R 星宣布相关