暑期创作大赛#
<!DOCTYPE html>
<html>
<head>
<title>My JSP Page</title>
</head>
<body>
<h1>Welcome to my JSP page!</h1>
</body>
</html>
<%
String message="Hello, JSP!";
out.println(message);
%>
<%@ 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>
<p>Today is ${today}</p>
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Hello, Servlet!");
}
}
<a href="${pageContext.request.contextPath}/hello">Click here</a> to say hello!
String name=request.getParameter("name");
request.getSession().setAttribute("username", "John");
String username=(String) request.getSession().getAttribute("username");
RequestDispatcher dispatcher=request.getRequestDispatcher("/anotherPage.jsp");
dispatcher.forward(request, response);
response.sendRedirect("http://www.example.com");
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");
Statement statement=conn.createStatement();
ResultSet resultSet=statement.executeQuery("SELECT * FROM users");
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();
<%@ taglib prefix="mytags" uri="/WEB-INF/mytags.tld" %>
<mytags:customTag />
public class CustomTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
JspWriter out=getJspContext().getOut();
out.println("This is a custom tag.");
}
}
<mytags:customTag />
<%-- JSP表达式 --%>
<p>2 + 2=<%=2 + 2 %></p>
<%-- JSP脚本片段 --%>
<% int count=0; %>
JSP复制<% if (condition) { %>
<p>This is true.</p>
<% } else { %>
<p>This is false.</p>
<% } %>
<% for (int i=0; i < 5; i++) { %>
<p>Iteration <%=i+1 %></p>
<% } %>
<% try {
// 代码块
} catch (Exception e) {
out.println("An error occurred: " + e.getMessage());
}
%>
<%@ include file="header.jsp" %>
<jsp:useBean id="user" class="com.example.User" scope="request" />
<p>Hello, <%=user.getName() %>!</p>
<%@ include file="header.jsp" %>
<p>This is the content.</p>
<%@ include file="footer.jsp" %>
<%
response.setHeader("Content-Type", "text/plain");
response.setHeader("Cache-Control", "no-cache");
%>
<% String ipAddress=request.getRemoteAddr();%>
<form action="processForm.jsp" method="post">
<input type="text" name="name" />
<input type="submit" value="Submit" />
</form>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
<p>Your session ID is <%=session.getId() %></p>
<%
Cookie cookie=new Cookie("username", "John");
response.addCookie(cookie);
%>
<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" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
</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" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
</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 (可变长类型),如图。
首先我们先有个页面,有基本的用户名框,密码框,两按钮,一个注册,一个注销,通过 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 大法,这里就给出重点要改的代码。
里面要重点改的代码,一个是 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
*请认真填写需求信息,我们会在24小时内与您取得联系。