整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          技術干貨-JSP(Java Server Pages

          技術干貨-JSP(Java Server Pages) Web應用程序開發中的常見代碼用法

          暑期創作大賽#

          創建一個JSP頁面:

          <!DOCTYPE html>
          <html>
          <head>
              <title>My JSP Page</title>
          </head>
          <body>
              <h1>Welcome to my JSP page!</h1>
          </body>
          </html>

          在JSP頁面中使用Java代碼:

          <% 
              String message="Hello, JSP!";
              out.println(message);
          %>

          在JSP頁面中使用JSTL標簽庫:

          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          
          <c:set var="name" value="John" />
          <c:if test="${name eq 'John'}">
              <p>Welcome, ${name}!</p>
          </c:if>

          在JSP頁面中使用EL表達式:

          <p>Today is ${today}</p>

          創建一個Servlet類:

          @WebServlet("/hello")
          public class HelloServlet extends HttpServlet {
              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  response.getWriter().append("Hello, Servlet!");
              }
          }

          在JSP頁面中引用Servlet:

          <a href="${pageContext.request.contextPath}/hello">Click here</a> to say hello!

          獲取請求參數:

          String name=request.getParameter("name");

          設置Session屬性:

          request.getSession().setAttribute("username", "John");

          獲取Session屬性:

          String username=(String) request.getSession().getAttribute("username");

          轉發請求到另一個頁面:

          RequestDispatcher dispatcher=request.getRequestDispatcher("/anotherPage.jsp");
          dispatcher.forward(request, response);

          重定向請求到另一個頁面:

          response.sendRedirect("http://www.example.com");

          使用JDBC連接數據庫:

          Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");

          執行SQL查詢:

          Statement statement=conn.createStatement();
          ResultSet resultSet=statement.executeQuery("SELECT * FROM users");

          處理SQL查詢結果:

          while (resultSet.next()) {
              String username=resultSet.getString("username");
              int age=resultSet.getInt("age");
              // 處理結果
          }

          插入數據到數據庫:

          PreparedStatement statement=conn.prepareStatement("INSERT INTO users (username, age) VALUES (?, ?)");
          statement.setString(1, "John");
          statement.setInt(2, 25);
          statement.executeUpdate();

          更新數據庫中的數據:

          PreparedStatement statement=conn.prepareStatement("UPDATE users SET age=? WHERE username=?");
          statement.setInt(1, 30);
          statement.setString(2, "John");
          statement.executeUpdate();

          刪除數據庫中的數據:

          PreparedStatement statement=conn.prepareStatement("DELETE FROM users WHERE username=?");
          statement.setString(1, "John");
          statement.executeUpdate();

          使用JSP自定義標簽庫:

          <%@ taglib prefix="mytags" uri="/WEB-INF/mytags.tld" %>
          
          <mytags:customTag />

          創建自定義JSP標簽:

          public class CustomTag extends SimpleTagSupport {
              public void doTag() throws JspException, IOException {
                  JspWriter out=getJspContext().getOut();
                  out.println("This is a custom tag.");
              }
          }

          在JSP頁面中使用自定義標簽:

          <mytags:customTag />

          使用JSP表達式和腳本片段:

          <%-- JSP表達式 --%>
          <p>2 + 2=<%=2 + 2 %></p>
          
          <%-- JSP腳本片段 --%>
          <% int count=0; %>

          在JSP頁面中使用條件語句:

          JSP復制<% if (condition) { %>
              <p>This is true.</p>
          <% } else { %>
              <p>This is false.</p>
          <% } %>

          在JSP頁面中使用循環語句:

          <% for (int i=0; i < 5; i++) { %>
              <p>Iteration <%=i+1 %></p>
          <% } %>

          在JSP頁面中處理異常:

          <% try {
              // 代碼塊
              } catch (Exception e) {
                  out.println("An error occurred: " + e.getMessage());
              }
          %>

          在JSP頁面中使用包含文件:

          <%@ include file="header.jsp" %>

          在JSP頁面中使用JavaBean:

          <jsp:useBean id="user" class="com.example.User" scope="request" />

          在JSP頁面中調用JavaBean的方法:

          <p>Hello, <%=user.getName() %>!</p>

          使用JSP頁面重用片段:

          <%@ include file="header.jsp" %>
          <p>This is the content.</p>
          <%@ include file="footer.jsp" %>

          在JSP頁面中設置響應頭:

          <%
              response.setHeader("Content-Type", "text/plain");
              response.setHeader("Cache-Control", "no-cache");
          %>

          在JSP頁面中獲取客戶端IP地址:

          <%    String ipAddress=request.getRemoteAddr();%>

          在JSP頁面中處理表單提交:

          <form action="processForm.jsp" method="post">
              <input type="text" name="name" />
              <input type="submit" value="Submit" />
          </form>

          在JSP頁面中處理文件上傳:

          <form action="upload.jsp" method="post" enctype="multipart/form-data">
              <input type="file" name="file" />
              <input type="submit" value="Upload" />
          </form>

          在JSP頁面中使用會話跟蹤:

          <p>Your session ID is <%=session.getId() %></p>

          在JSP頁面中使用Cookie:

          <%
              Cookie cookie=new Cookie("username", "John");
              response.addCookie(cookie);
          %>

          在JSP頁面中重復使用片段:

          <jsp:include page="common.jsp">
              <jsp:param name="name" value="John" />
          </jsp:include>

          這些示例展示了JSP Web應用程序開發中的一些常見代碼用法,涵蓋了JSP頁面、Servlet、數據庫操作、自定義標簽和其他各種功能。實際開發中,根據具體需求可能會有更多的代碼邏輯和功能實現。

          種包管理器到ESLint,從CommonJS到AMD,再從ES6模塊到Babel和Webpack,好多工具啊!

          好累……

          是的,今天我覺得很疲勞。我不禁想,我本應該繼續我的銷售職業,不應該抄近路做前端開發。但我意識到,前端開發是給勇敢者準備的,而勇敢者絕不會放棄,他們才是人生贏家。

          所以我決定做人生贏家,我要寫點東西給前端開發和工具鏈疲勞的受害者們看。我要寫一下我是怎樣將初學者級別的代碼變成令人贊嘆的產品級代碼的,以及這個過程中我用到的工具。

          現在開始吧!

          我們在做的東西

          其實沒什么令人激動的東西。我們做了個Web應用,從某個API讀取一些隨機的用戶,然后顯示在前端上。它沒有路由的能力。本文的最終目標是讓你熟悉前端的工具鏈。

          我們的AngularJS代碼中沒有使用樣板代碼,所以我們不會被CLI的那些黑科技搞得暈頭轉向。注意我用的是AngularJS,不是Angular。使用AngularJS的原因是我找不到任何關于AngularJS工具鏈和打包的文章。

          首先在根目錄下建一個index文件。

          <html>

          <head>

          <title>Random User!</title>

          <link rel="stylesheet" >

          </head>

          <body>

          <div class="container">

          <h1 class="text-center">Random User!</h1>

          </div>

          <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>

          </body>

          </html>

          中規中矩的老式代碼。這段代碼從CDN上加載AngularJS文件和一個最小化的CSS框架,然后開始一點點編寫JavaScript代碼并添加到index中。

          但隨著應用程序的增長,我們有必要跟蹤所有的依賴(這里的依賴就是Angular)。

          使用包管理器

          許多人使用包管理器跟蹤項目所需的依賴的版本。包管理器的最大賣點就是,它會訪問依賴的GitHub主頁,下載到你的文件夾里,并且跟蹤下載的版本。這樣可以保證,移動代碼位置或者下載其他版本的依賴不會造成代碼無法工作。

          代碼管理器有過duojs、jspm、bower、npm,現在還有Yarn。現在去裝一個yarn,我們稍后會用到。

          向應用程序里添加依賴時,yarn會下載所需的文件,并保存到node_modules文件夾中。之后,需要用到依賴時,可以在index文件里引入:

          裝好這個后,我們再往根目錄下添加app.js、userController.js和userFactory.js文件,然后全都鏈接到index文件里。

          /**

          * /app.js

          */

          var app=angular.module("RandomApp", []);

          // /userFactory.js

          app.factory("UserF", function($http) {

          var UserF={};

          UserF.getUsers=function(){

          return $http({

          method: 'GET',

          url: 'https://www.reqres.in/api/users',

          })

          };

          return UserF;

          });

          // /userController.js

          app.controller("userController", function($scope, UserF){

          $scope.users=[];

          UserF.getUsers()

          .then(function(res) {

          $scope.users=res.data.data;

          })

          });

          <!doctype html>

          <html lang="en">

          <head>

          <meta charset="UTF-8">

          <meta name="viewport"

          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

          <meta http-equiv="X-UA-Compatible" content="ie=edge">

          <title>Random User!</title>

          <link rel="stylesheet" >

          </head>

          <body>

          <div class="container" ng-app="RandomApp">

          <h1 class="text-center">Random User!</h1>

          <div ng-controller="userController">

          <div ng-repeat="user in users">

          <div class="card">

          <div class="card-image">

          <img ng-src="{{user.avatar}}" class="img-responsive">

          </div>

          <div class="card-header">

          <div class="card-title h5">{{user.first_name}} {{user.last_name}}</div>

          </div>

          </div>

          </div>

          </div>

          </div>

          <script src="node_modules/angular/angular.min.js"></script>

          <script src="app.js"></script>

          <script src="userController.js"></script>

          <script src="userFactory.js"></script>

          </body>

          </html>

          index越來越大了。他遇到了他自己的問題。他的手心開始出汗,膝蓋發軟,胳膊也越來越沉重……

          這種方式的問題

          所有的script標簽必須按照固定的順序。app.js生成app,然后附加到全局的window對象上。這個app變量會被其他腳本文件用到。這種情況通常被稱為“全局命名空間污染”。

          如果你還在用這種方式,就趁早改了吧。它的問題是,不管我們什么時候打開哪個文件,都無法得知app變量的值究竟是什么。

          這段代碼的另一個語義上的問題是,它使用了匿名函數。匿名函數是JavaScript的天使,也是魔鬼。

          永遠不要忘記給匿名函數起名字。這樣以后調試代碼會變得容易很多。

          那么,要是有個JS警察負責找出這些問題,豈不是很好?

          ESLint

          ESLint是個清理器。就像個嚴格的結對編程的伙伴一樣。清理器會在你運行應用程序之前就幫你調試代碼,并且強迫你和你的團隊遵循整潔代碼的實踐。誰說這樣的老師不存在的?

          配置ESLint

          我們使用Airbnb的樣式配置,在我們編寫代碼時進行檢查,并指出不當的地方。上面的命令會將配置安裝到node_modules目錄下,但我們得告訴ESLint怎么用這個配置。建立一個名為.eslintrc.json的文件,內容如下:

          // .eslintrc.json

          {

          "extends": [

          "airbnb/legacy"

          ],

          "env": {

          "browser": true

          }

          }

          extends列表告訴ESLint在它自己的默認規則之上使用Airbnb的規則。env變量告訴ESLint不要抱怨沒有初始化的window變量等。要清理所有文件,可以使用通配符 * 。

          現在運行下ESLint看看有什么結果。

          這些都是Airbnb樣式指南定義的規則。我留給你自己去改正這些文件。一開始就有個清理器是最理想的。當然,你可以關閉某個特定的規則。

          比如,如果你喜歡不用分號,或者使用雙引號而不是單引號,你可以關閉相應的規則。ESLint很靈活,允許你這么做。

          模塊

          現在來討論下模塊。在創建大規模應用時,我們要求代碼有良好的結構,以便于以后的擴展。

          我們把代碼放到不同的模塊中,以實現代碼分割的目的。JavaScript直到ES6才支持模塊。但模塊化的概念早在ES6之前就出現了。

          CommonJS

          在ES6之前,人們使用CommonJS標準。你可以寫一段代碼,然后告訴環境導出這段代碼。之后就能使用像RequireJS之類的庫導入模塊了。

          // util.js

          module.export={

          noop: function(){},

          validateUrl: function(s){

          return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)

          }

          };

          // postController.js

          var validateUrl=require('./util').validateUrl;

          var handleSubmit=function handleSubmit(e) {

          if(!validateUrl(e.target.value)) {

          return;

          }

          submitUrl(e.target.value);

          }

          如果你玩過Node,你會覺得這段代碼看起來很眼熟。不過這個標準有個缺陷——它是同步的。

          也就是說,只有在validateUrl被require了之后,postController的第3行的handleSubmit才會被執行。在這之前代碼會暫停。

          這種體系在Node.js中沒什么問題。Node可以在服務器啟動之前加載所有依賴,比如配置日志文件、連接云端的數據庫、配置秘鑰等。但在前端,這種方法并不是太理想。

          異步模塊定義(Asynchronous Module Definition,AMD)

          顧名思義,這種方式會異步加載模塊,比CommonJS的方式好一些。下面是使用AMD的代碼(我加了幾個函數)。看著眼熟嗎?

          define(['validateSpam', 'blockUser', function(validateSpam, blockUser){

          return {

          noop: function(){},

          validateUrl: function(s) {

          return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)

          },

          validateSpammyComment: function validateSpammyComment(comment, userID) {

          if(validateSpam(comment)) {

          blockUser(userID);

          return false;

          }

          return true;

          }

          }])

          第1行看起來就像AngularJS中的依賴注入一樣。

          ES6模塊

          TC39委員會看到開發者們使用外部庫之后,他們深切感受到JavaScript需要支持模塊。因此他們在ES6中引入了模塊功能。現在使用ES6吧!

          function noop(){};

          function validateUrl(s) {

          return s.matches(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/)

          }

          export {

          noop,

          validateUrl

          }

          import { validateUrl } from './util';

          var handleSubmit=function handleSubmit(e) {

          if(!validateUrl(e.target.value)) {

          return;

          }

          submitUrl(e.target.value);

          }

          不需要再調用外部庫。import和export都是原生支持的。但依然有些版本的瀏覽器并不能完全支持ES6的所有功能。

          但這種瀏覽器之間的不一致并不能阻止程序員編寫下一代的JavaScript。像babel等工具可以掃描所有JavaScript,并將它們轉譯成能兼容所有瀏覽器的代碼。因此,你的代碼甚至可以支持IE之類的老瀏覽器。

          Babel和ES6

          好了,現在我們把舊的JavaScript轉換成新的JavaScript。先做一點改動,以便添加模塊功能。現在我們先不管清理器……讓它去抱怨吧。

          // /userFactory.js

          let angular=window.angular;

          let app=angular.module('RandomApp');

          /**

          * A User factory which gets the user list

          * @param $http

          */

          let userFactory=$http=> {

          let UserF={};

          UserF.getUsers=()=> $http({

          method: 'GET',

          url: 'https://www.reqres.in/api/users'

          });

          return UserF;

          };

          app.factory('UserF', userFactory);

          // /userController.js

          let angular=window.angular;

          let app=angular.module('RandomApp');

          /**

          * Controls the user

          * @param $scope

          * @param UserF

          */

          let userController=($scope, UserF)=> {

          $scope.users=[];

          UserF.getUsers().then(res=> $scope.users=res.data.data);

          };

          userController.$inject=['$scope', 'UserFactory'];

          app.controller('userController', userController);

          這段代碼的問題

          這段代碼無法工作。因為ES6的let關鍵字創建的變量是代碼塊上下文內的變量,而在同一個上下文內無法重復定義代碼塊級別的變量。

          別忘了:我們還在全局上下文里呢。現在來改正這個問題。

          我希望重構代碼的原因是,我想引入babel,這樣可以親眼看看babel的魔法。現在可以在終端里安裝babel:yarn add babel-cli babel-preset-env

          這行命令會安裝babel-cli和babel-preset-env。

          babel插件和預設

          JavaScript代碼會通過一系列轉換器,而我們可以選擇需要什么轉換器。你可以讓它把箭頭函數轉換成匿名函數,轉換擴展運算符(spread),轉換for...of循環,等等。這些轉換器叫做插件。

          你可以選擇任何你想要的插件。成組的插件叫做預設。babel-preset-env會給babel一個靈活的目標。

          它并不是指定某個特定版本的JavaScript,而是告訴babel自動跟蹤最新的n個版本瀏覽器。

          現在來設置babel配置文件:.babelrc,把它放到根目錄下。

          {

          "presets": [

          ["env", {

          "targets": {

          "browsers": "last 2 versions"

          }

          }]

          ]

          }

          現在從終端運行如下命令,babel就能正常工作。輸入以下命令:

          node_modules/.bin/babel *.js

          很方便對吧?babel會在轉換之前預覽以下。

          現在喘口氣,考慮下我們學過的東西。我們將一個JavaScript文件分解成了許多個文件。我們添加了清理器,防止寫出不合規范的代碼。

          我們使用未來的JavaScript語法,并將其轉換成特定版本的瀏覽器能理解的東西。我們污染了全局命名空間,但暫時還能接受,我們稍后會解決這個問題。

          如果有個工具能自動完成這一切就好了。我們給它所有代碼,自動運行清理器找出所有錯誤,然后轉譯成瀏覽器兼容的代碼。沒錯,確實有這么個工具。現在把這些東西都自動化吧。

          用Webpack進行構建

          首先,把所有JS文件都移動到一個目錄下。我們使用標準的命名方式,將文件夾命名為build。同時,我們重構下JavaScript文件,這樣所有文件都能被構建到同一個文件下。

          // /build/userController.js

          /**

          * Controls the user

          * @param $scope

          * @param UserF

          */

          let userController=($scope, UserF)=> {

          $scope.users=[];

          UserF.getUsers().then(res=> $scope.users=res.data.data);

          };

          userController.$inject=['$scope', 'userFactory'];

          export default userController;

          // /build/userFactory.js

          /**

          * A User factory which gets the user list

          * @param $http

          */

          let userFactory=$http=> {

          let UserF={};

          UserF.getUsers=()=> $http({

          method: 'GET',

          url: 'https://www.reqres.in/api/users'

          });

          return UserF;

          };

          userFactory.$inject=['$http'];

          export default userFactory;

          /// /build/app.js

          import angular from 'angular';

          import userController from './userController';

          import userFactory from './userFactory';

          angular.module('RandomApp', [])

          .factory('userFactory', userFactory)

          .controller('userController', userController);

          現在創建webpack.config.js文件:

          var path=require('path');

          module.exports={

          mode: 'development', // tells webpack that this is a development build. the 'production' switch will minify the code among other things

          devtool: 'cheap-eval-source-map', // generate source maps for better debugging and dont take much time.

          context: __dirname, // since this runs in a node environment, webpack will need the current directory name

          entry: './build/app.js', // take this file and add to the bundled file whatever this file imports

          output: {

          path: path.join(__dirname, 'dist'), // output this in a dist folder

          filename: 'bundle.js' // and name it bundle.js

          },

          // read medium post to know what's module and devServer because I dont have much room for comments

          module: {

          rules: [{

          enforce: 'pre',

          loader: 'eslint-loader',

          test: /\.js$/

          }, {

          loader: 'babel-loader',

          test: /\.js$/

          }]

          },

          devServer: {

          publicPath: '/dist/',

          filename: 'bundle.js',

          historyApiFallback: true,

          overlay: true

          }

          };

          如果現在運行webpack,就會看到所有文件都被打包成一個文件,放到dist目錄下:

          webpack配置揭秘

          祝賀你,給自己點獎勵吧。現在我們把所有文件都打包到一起,它幾乎可以用于生產環境了。

          現在來討論下這個配置。我會逐一介紹每個配置項的意思。更詳細的資料可以參考手冊(https://webpack.js.org/)。

          大多數配置項我都給出了注釋。這里說說沒加注釋的那些。

          Webpack加載器(module對象)

          這個可以想像成一條流水線上的一串代碼加載單元。最后一個加載器(這里是babel-loader)會最先被Webpack用來加載代碼。

          我們要求webpack遍歷所有代碼,然后用babel-loader將代碼轉譯成ES5。

          加載器對象還需要一個test設置項。它用這個設置項來匹配所有它應該負責的文件(本例中用一段正則表達式匹配了所有擴展名為.js的文件)。

          轉譯之后,就執行下一個加載器(這里是eslint-loader)。最后,把所有改變從內存中寫到文件中,然后輸出到output對象指定的文件里。

          但這并不是我們的配置文件的行為。我們在ESLint加載器上加了個enforce: pre,因為我們希望先運行清理器。

          這是因為輸出的結果只有一個文件,而且如果使用最小化和混淆功能的話,這個文件通常會變成人類無法閱讀的格式(生產環境中經常會如此)。

          清理器看這個文件就會瘋了。這不是我們想要的,所以我們希望webpack先運行清理器,再進行轉譯。

          除此之外,你還可以使用好幾個加載器,可以加載樣式表文件、SVG圖像,以及字體。有個我總會用到的加載器就是html-loader。

          HTML加載器

          在Angular下,我們通常會在directive/component中包含模板文件,因此可以在Webpack中使用html-loader進行加載。

          templateUrl: './users/partial/user.tpl.html' // 把這種寫法改成:templateUrl: require('./users/partial/user.tpl.html')

          Webpack由一個超大規模的社區支持,他們寫了很多優秀的加載器,以及很完善的文檔。不管你有什么需求,很可能已經有現成的加載器了。

          Webpack開發服務器(devServer)

          Webpack開發服務器是個獨立于Webpack的模塊。它會啟動自己的服務器,然后監視任何文件的改動。如果文件發生變化,Webpack開發服務器就會重新打包并自動刷新頁面。

          如果發生錯誤,它會在屏幕上顯示一個覆蓋層(通過overlay配置項設置),并直接在瀏覽器中顯示錯誤信息。而且它速度非常快,因為一切都在內存中完成,不會訪問硬盤。

          當然,為了運行webpack開發服務器,你首先得有一個基礎的構建好的文件(即,至少要運行webpack一次以生成構建好的文件)。

          一旦生成之后,就可以運行該命令。該命令會啟動服務器并提供靜態文件,打開瀏覽器(默認是8080端口),并持續監視任何變動。

          搞定了!

          不過這并不是結局。還有許多你能做的事情。在工作中,我們使用Flow在編碼時進行靜態類型檢查。

          靜態類型檢查器可以檢查代碼,并在發生錯誤時發出警告,比如調用函數時提供了錯誤類型的參數等。Flow也可以集成到Webpack中。

          我們還使用Prettier實現編碼時的自動格式化。它能讓代碼更可讀。

          傻瓜都能寫計算機能看懂的代碼。

          好的程序員寫人類能看懂的代碼。

          —— Martin Fowler。

          我要把這句話貼在我的桌子上。祝賀你!你成功了!

          如果你讀完了這篇超長的文章,我要跟你擊掌向你道喜,你是人生贏家。JavaScript對我而言并不容易。

          我很希望我在第一個項目中編寫UI時能懂得這些東西。但我估計這就是前端開發對我的意義。持續學習,持續進步。

          原文:https://medium.freecodecamp.org/the-brain-fatigued-javascripters-guide-to-modern-frontend-tooling-in-2018-9818a04e9ec5

          作者:Amin Mohamed Ajani,Javascript開發人員,曾為FireFox開發工具貢獻代碼。用戶界面工程師,擅長iQuanti,reactjs,nodejs和TheIsmaili。

          譯者:彎月,責編:胡巍巍

          “征稿啦”

          CSDN 公眾號秉持著「與千萬技術人共成長」理念,不僅以「極客頭條」、「暢言」欄目在第一時間以技術人的獨特視角描述技術人關心的行業焦點事件,更有「技術頭條」專欄,深度解讀行業內的熱門技術與場景應用,讓所有的開發者緊跟技術潮流,保持警醒的技術嗅覺,對行業趨勢、技術有更為全面的認知。

          如果你有優質的文章,或是行業熱點事件、技術趨勢的真知灼見,或是深度的應用實踐、場景方案等的新見解,歡迎聯系 CSDN 投稿,聯系方式:微信(guorui_1118,請備注投稿+姓名+公司職位),郵箱(guorui@csdn.net)。

          一、寫在前面

          二、效果圖

          三、實現思路

          四、實現代碼

          1、login總界面

          2、registercheck總代碼

          3、logoutcheck總代碼

          4、amendcheck總代碼


          相關文章

          一、寫在前面

          哈嘍~大家好,這篇呢我們來看看用 JSP 連接 MySQL 登入注冊項目實踐,這里就可能有人問了,唉?追桑~前些天不是寫了 jsp 登入注冊的項目嗎?怎么這次還在寫呢?哈哈,您別擔心,這次呢,肯定和上次不同,我們先來看看效果吧!

          二、效果圖

          數據庫界面

          感覺是不是不一樣了,哈哈哈,那么接下來我們來看看是怎么實現的。

          三、實現思路

          首先我們這里很明顯,有四個總頁面分別是 login(登入界面)、logout(注銷界面)、amend(修改界面)、register(注冊界面),這四個總頁面分別對應著檢查頁面(check)、成功頁面(success)、失敗頁面(fail)。建立之好后,通過 from 的 action 來進行跳轉,我們先來看看 MySQL (數據庫)表名叫 login。

          我們這里數據庫共三列,第一列叫 name (用戶名)、pass(密碼)、time(注冊時間),name 與 pass 都是 int(整型) 類型的,time 是 varchar (可變長類型),如圖。

          四、實現代碼

          1、login總界面

          首先我們先有個頁面,有基本的用戶名框,密碼框,兩按鈕,一個注冊,一個注銷,通過 from進行跳轉,代碼如下

           <form method="post" action="check.jsp">
                  <input type="text" name="user" style="width: 300px;height: 50px" placeholder="請輸入用戶名:"
                  > <br>
                  <input type="password" name="pass" style="width: 300px;height: 50px" placeholder="請輸入密碼:" > <br>
                  <button type="submit" style="width:80px;height:40px; font-size: 20px" class="clear">登錄</button>
                  <button type="reset" style="width:80px;height:40px; font-size: 20px" class="clear">重置</button>
                  <br>
                  沒有賬號?<a href="register.jsp">點擊注冊</a><br>
                  不想用了?<a href="logout.jsp">點擊注銷</a>
              </form>
          

          用 check 連接數據庫(如何連接數據庫,前面文章已經給出了,有興趣的小伙伴可以看看前面寫的文章,也放在前面了) 同樣的道理,還是那五個步驟(這里就不過多的解釋,可以看看上面表格給出的文章),先來看看代碼。

          String user=request.getParameter("user"); // getParameter  與 getAttribute  區別
                  String pass=request.getParameter("pass");
                  // String getParameter(String name):根據參數名稱獲取參數值
                  // getAttribute()獲取的是服務器設置的數據。getAttribute() 方法返回指定屬性名的屬性值。
           
                  try {
                      Class.forName("com.mysql.cj.jdbc.Driver");
                      String url="jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC";
                      String user1="root";
                      String pass1="123456";
                      Connection connection=DriverManager.getConnection(url,user1,pass1);
                      String sql="select * from login where name=? and pass=?";
           
                      PreparedStatement ps=connection.prepareStatement(sql);
                      ps.setString(1,user);
                      ps.setString(2,pass);
                      ResultSet re=ps.executeQuery();
           
                      if (re.next()){
                          response.sendRedirect("loginsuccess.jsp");
                          session.setAttribute("user",user);
                      }else {
                          response.sendRedirect("loginfail.jsp");
                      }
           
                  } catch (ClassNotFoundException e) {
                      e.printStackTrace();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
          

          這里 response.sendRedirect 跳轉了兩個頁面一個 loginsuccess 和 loginfail 的兩個界面,下面我們來看看,這兩個文件(其實很簡單)

          loginsuccess 代碼

           <div class="form">
                          <h2> <h22>登錄成功</h22><br>
                          </h2>
                          <fon>恭喜您成功登入 <br>    歡迎使用 <br>
                              <a class="a1" href="login.jsp">返回登入界面</a>
                          </fon>
                      </div>
          

          loginfail 代碼:

          <h2> <h22>登錄失敗</h22><br>
                          </h2>
                          <fon>寶~是不是賬號或密碼記錯惹? <br>
                              <a class="a1" href="login.jsp">返回登入界面</a><br>
                              <p1><a href="amend.jsp">點擊修改密碼</a></p1>
                          </fon>

          這里我們點擊運行看看效果

          這里我們用兩個升級 大裝備(html)(css) 來美化一下我們的頁面,這里我們頁面美化的,用的是這位大佬的頁面(博主名為鍵盤奏鳴曲),大家可以來看看,點擊鏈接

          HTML 代碼

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>

          <head>

          <meta charset="UTF-8">

          <meta name="viewport" content="width=device-width, initial-scale=1.0">

          <link rel="stylesheet" href="css.css">

          <title>123</title>



          </head>

          <body>


          <section>

          <div class="color"></div>

          <div class="color"></div>

          <div class="color"></div>

          <div class="box">

          <div class="circle" style="--x:0"></div>

          <div class="circle" style="--x:1"></div>

          <div class="circle" style="--x:2"></div>

          <div class="circle" style="--x:3"></div>

          <div class="circle" style="--x:4"></div>

          <div class="container">

          <div class="form">

          <h2>登錄</h2>

          <form method="post" action="check.jsp">

          <div class="inputBox">

          <input type="text" placeholder="姓名" name="user">


          </div>

          <div class="inputBox">

          <input type="password" placeholder="密碼" name="pass">


          </div>

          <div class="inputBox">

          <input type="submit" value="登錄">


          </div>

          <p class="forget">不想用了?<a href="logout.jsp">

          點擊這里

          </a></p>

          <p class="forget">沒有賬戶?<a href="register.jsp">

          注冊

          </a></p>

          </form>

          </div>

          </div>

          </div>

          </section>

          </body>


          </html>

          CSS 代碼

          /*.center{*/
          /*    text-align:center;*/
          /*    margin-top: 50px;*/
          /*}*/
          .fon{
              font-size: 40px;
          }
          /*body{*/
          /*    background: url("images/image-2.jpg") no-repeat 0 0;*/
          /*    background-size: 100% 100%;*/
          /*    text-decoration:none;*/
          /*}*/
           
          /*input {*/
          /*    background-color: transparent;*/
          /*    outline: none;*/
          /*    color: black;*/
          /*}*/
          /*.clear{*/
          /*    opacity:0.3;*/
          /*}*/
           
          * {
              margin: 0;
              padding: 0;
              box-sizing: border-box;
          }
           
          /* 使用flex布局,讓內容垂直和水平居中 */
           
          section {
              /* 相對定位 */
              position: relative;
              overflow: hidden;
              display: flex;
              justify-content: center;
              align-items: center;
              min-height: 100vh;
              /* linear-gradient() 函數用于創建一個表示兩種或多種顏色線性漸變的圖片 */
              background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
          }
           
          /* 背景顏色 */
           
          section .color {
              /* 絕對定位 */
              position: absolute;
              /* 使用filter(濾鏡) 屬性,給圖像設置高斯模糊*/
              filter: blur(200px);
          }
           
          /* :nth-child(n) 選擇器匹配父元素中的第 n 個子元素 */
           
          section .color:nth-child(1) {
              top: -350px;
              width: 600px;
              height: 600px;
              background: #ff359b;
          }
           
          section .color:nth-child(2) {
              bottom: -150px;
              left: 100px;
              width: 500px;
              height: 500px;
              background: #fffd87;
          }
           
          section .color:nth-child(3) {
              bottom: 50px;
              right: 100px;
              width: 500px;
              height: 500px;
              background: #00d2ff;
          }
           
          .box {
              position: relative;
          }
           
          /* 背景圓樣式 */
           
          .box .circle {
              position: absolute;
              background: rgba(255, 255, 255, 0.1);
              /* backdrop-filter屬性為一個元素后面區域添加模糊效果 */
              backdrop-filter: blur(5px);
              box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
              border: 1px solid rgba(255, 255, 255, 0.5);
              border-right: 1px solid rgba(255, 255, 255, 0.2);
              border-bottom: 1px solid rgba(255, 255, 255, 0.2);
              border-radius: 50%;
              /* 使用filter(濾鏡) 屬性,改變顏色。
              hue-rotate(deg)  給圖像應用色相旋轉
              calc() 函數用于動態計算長度值
              var() 函數調用自定義的CSS屬性值x*/
              filter: hue-rotate(calc(var(--x) * 70deg));
              /* 調用動畫animate,需要10s完成動畫,
              linear表示動畫從頭到尾的速度是相同的,
              infinite指定動畫應該循環播放無限次*/
              animation: animate 10s linear infinite;
              /* 動態計算動畫延遲幾秒播放 */
              animation-delay: calc(var(--x) * -1s);
          }
           
          /* 背景圓動畫 */
           
          @keyframes animate {
              0%, 100% {
                  transform: translateY(-50px);
              }
              50% {
                  transform: translateY(50px);
              }
          }
           
          .box .circle:nth-child(1) {
              top: -50px;
              right: -60px;
              width: 100px;
              height: 100px;
          }
           
          .box .circle:nth-child(2) {
              top: 150px;
              left: -100px;
              width: 120px;
              height: 120px;
              z-index: 2;
          }
           
          .box .circle:nth-child(3) {
              bottom: 50px;
              right: -60px;
              width: 80px;
              height: 80px;
              z-index: 2;
          }
           
          .box .circle:nth-child(4) {
              bottom: -80px;
              left: 100px;
              width: 60px;
              height: 60px;
          }
           
          .box .circle:nth-child(5) {
              top: -80px;
              left: 140px;
              width: 60px;
              height: 60px;
          }
           
          /* 登錄框樣式 */
           
          .container {
              position: relative;
              width: 400px;
              min-height: 400px;
              background: rgba(255, 255, 255, 0.1);
              display: flex;
              justify-content: center;
              align-items: center;
              backdrop-filter: blur(5px);
              box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
              border: 1px solid rgba(255, 255, 255, 0.5);
              border-right: 1px solid rgba(255, 255, 255, 0.2);
              border-bottom: 1px solid rgba(255, 255, 255, 0.2);
          }
           
          .form {
              position: relative;
              width: 100%;
              height: 100%;
              padding: 50px;
          }
           
          /* 登錄標題樣式 */
           
          .form h2 {
              text-align: center;
              position: relative;
              color: #fff;
              font-size: 40px;
              font-weight: 600;
              letter-spacing: 5px;
              margin-bottom: 30px;
              cursor: pointer;
          }
           
          .form h2 h22 {
              top: -40px;
              text-align: center;
              position: relative;
              color: #fff;
              font-size: 40px;
              font-weight: 600;
              letter-spacing: 5px;
              margin-bottom: 30px;
              cursor: pointer;
          }
           
          .form .a1, .form p1 {
              bottom: -90px;
              left: 50px;
              position: relative;
              color: #fff;
              font-size: 18px;
              font-weight: 600;
              letter-spacing: 5px;
              /*margin-bottom: 10px;*/
              cursor: pointer;
              text-decoration: none;
          }
           
          .form p1 a{
           
              position: relative;
              color: #fff;
              font-size: 18px;
              font-weight: 600;
              letter-spacing: 5px;
              /*margin-bottom: 10px;*/
              cursor: pointer;
              text-decoration: none;
          }
           
          .form fon {
              top: -30px;
              left: 30px;
              position: relative;
              color: #fff;
              font-size: 28px;
              font-weight: 600;
              letter-spacing: 5px;
              margin-bottom: 30px;
              cursor: pointer;
          }
          /* 登錄標題的下劃線樣式 */
           
          .form h2::before {
              content: "";
              position: absolute;
              left: 0;
              bottom: -10px;
              width: 0px;
              height: 3px;
              background: #fff;
              transition: 0.5s;
          }
           
          .form h2 h22::before {
              content: "";
              position: absolute;
              /*left: 0;*/
              /*bottom: -10px;*/
              /*width: 0px;*/
              /*height: 3px;*/
              /*background: #fff;*/
              /*transition: 0.5s;*/
          }
           
          .form h2:hover:before {
              width: 53px;
          }
           
          .form .inputBox {
              width: 100%;
              margin-top: 20px;
          }
           
          /* 輸入框樣式 */
           
          .form .inputBox input {
              width: 100%;
              padding: 10px 20px;
              background: rgba(255, 255, 255, 0.2);
              outline: none;
              border: none;
              border-radius: 30px;
              border: 1px solid rgba(255, 255, 255, 0.5);
              border-right: 1px solid rgba(255, 255, 255, 0.2);
              border-bottom: 1px solid rgba(255, 255, 255, 0.2);
              font-size: 16px;
              letter-spacing: 1px;
              color: #fff;
              box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
          }
           
          .form .inputBox input::placeholder {
              color: #fff;
          }
           
          /* 登錄按鈕樣式 */
           
          .form .inputBox input[type="submit"],.form .inputBox input[type="reset"]  {
              background: #fff;
              color: #666;
              max-width: 100%;
              margin-bottom: 20px;
              font-weight: 600;
              cursor: pointer;
          }
           
          .forget {
              margin-top: 6px;
              color: #fff;
              letter-spacing: 1px;
          }
           
          .forget a {
              color: #fff;
              font-weight: 600;
              text-decoration: none;
          }
          

          同樣的道理我們來升級一下 loginsuccess 與 loginfail 。

          loginsuccess 代碼

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>登入成功界面</title>
              <link rel="stylesheet" href="css.css" type="text/css">
          </head>
          <body>
          <%--<div class="center">--%>
          <%--    <p class="fon">登入成功界面</p>--%>
          <%--    <p class="fon1">恭喜您成功登入,歡迎使用</p>--%>
          <%--    <a href="login.jsp">點擊退出,返回登入界面</a>--%>
          <%--</div>--%>
           
          <section>
              <div class="color"></div>
              <div class="color"></div>
              <div class="color"></div>
              <div class="box">
                  <div class="circle" style="--x:0"></div>
                  <div class="circle" style="--x:1"></div>
                  <div class="circle" style="--x:2"></div>
                  <div class="circle" style="--x:3"></div>
                  <div class="circle" style="--x:4"></div>
                  <div class="container">
                      <div class="form">
                          <h2> <h22>登錄成功</h22><br>
                          </h2>
                          <fon>恭喜您成功登入 <br>    歡迎使用 <br>
                              <a class="a1" href="login.jsp">返回登入界面</a>
                          </fon>
                      </div>
                  </div>
              </div>
          </section>
           
          </body>
          </html>
          

          loginfail 代碼

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>登入失敗界面</title>
              <link rel="stylesheet" href="css.css" type="text/css">
          </head>
          <body>
          <%--<div class="center">--%>
          <%--    <p class="fon">登入失敗界面</p>--%>
          <%--    <p class="fon1">對不起,您賬號或密碼有誤,請返回登入界面</p>--%>
          <%--    <a href="login.jsp">返回登入界面</a><br>--%>
          <%--    忘記密碼?<a href="amend.jsp">點擊修改密碼</a>--%>
          <%--</div>--%>
           
          <section>
              <div class="color"></div>
              <div class="color"></div>
              <div class="color"></div>
              <div class="box">
                  <div class="circle" style="--x:0"></div>
                  <div class="circle" style="--x:1"></div>
                  <div class="circle" style="--x:2"></div>
                  <div class="circle" style="--x:3"></div>
                  <div class="circle" style="--x:4"></div>
                  <div class="container">
                      <div class="form">
                          <h2> <h22>登錄失敗</h22><br>
                          </h2>
                          <fon>寶~是不是賬號或密碼記錯惹? <br>
                              <a class="a1" href="login.jsp">返回登入界面</a><br>
                              <p1><a href="amend.jsp">點擊修改密碼</a></p1>
                          </fon>
                          
                      </div>
                  </div>
              </div>
          </section>
           
          </body>
          </html>
          

          點擊運行,我們來看看效果

          那么這里我們是完成了,login總界面的效果,同樣的道理,代碼都差不多,我們直接 cv 大法,這里就給出重點要改的代碼。

          2、registercheck總代碼

          里面要重點改的代碼,一個是 sql 語句插入,另一個是時間格式轉換。

          tring sql="insert into login(name, pass,time)VALUES(?,?,?)";

          SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 時間轉換,要不然就會是國際時間格式

          String data=formatter.format(new Date());// 記錄的是當前的時間

          ps.setString(3,data);

          3、logoutcheck總代碼

          3、logoutcheck總代碼

          里面要重點改的代碼,是 sql 語句刪除。

          String sql="DELETE FROM login WHERE name=? and pass=?";

          4、amendcheck總代碼

          里面要重點改的代碼,是 sql 語句更新。

          String sql="update login set pass='"+pass+"'";

          然后分別是各個總頁面的 success 與 fail 頁面來實現好,這里有一個小細節,我們在作拋出異常,這里可以 out.println 來打印出信息來測試,可以輸出在網頁上,這樣可以方便知道那里有異常。

          
          catch (ClassNotFoundException e) {
                      e.printStackTrace();
                      out.println("1");
                      // response.sendRedirect("registerfail.jsp");
                  } catch (SQLException e) {
                      e.printStackTrace();
                      out.println("2");
                      // response.sendRedirect("registerfail.jsp");
          
          

          好了,點擊運行,完成總效果。



































          作者:一個名叫追的程序猿

          原文出處:https://blog.csdn.net/aasd23/article/details/124458396?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-16-124458396-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-16-124458396-null-null.nonecase


          主站蜘蛛池模板: 狠狠做深爱婷婷久久综合一区| 国产熟女一区二区三区四区五区 | 四虎永久在线精品免费一区二区 | 成人影片一区免费观看| 无码8090精品久久一区| 久久影院亚洲一区| 日韩成人无码一区二区三区 | 精品国产不卡一区二区三区 | 美女视频一区二区| 色妞色视频一区二区三区四区| 国产成人一区二区三区免费视频 | 无码人妻久久一区二区三区| 亚洲熟女乱色一区二区三区 | 国产AV天堂无码一区二区三区| 女同一区二区在线观看| 国产在线精品一区二区三区直播| 国产日韩一区二区三区在线播放| 久久婷婷色综合一区二区| 精品福利一区二区三| 亚洲中文字幕无码一区| 亚洲日韩AV一区二区三区中文| 亚洲一区免费视频| 亚洲AV无码片一区二区三区| 国产精品99无码一区二区| 亚洲国产精品一区二区第一页免| 国产午夜福利精品一区二区三区 | 中文字幕一区二区三匹| 国模吧无码一区二区三区| 久久一区二区三区99| 中文字幕无线码一区2020青青| 亚洲一区二区久久| 亚洲啪啪综合AV一区| 国产精品无码一区二区三级| 亚洲一区二区三区在线网站| 日本在线视频一区| 国产在线精品一区二区夜色| 国产观看精品一区二区三区| 亚洲色精品三区二区一区 | chinese国产一区二区| 一区二区三区在线|日本| 无码日韩精品一区二区三区免费|