Web开发实训——学生信息管理系统(JSP+Servlet+Ajax+MySQL)
内容比较长、是完整的开发过程,可以根据目录查看感兴趣的地方。
目录
核心思路
开发环境
完成结果
一、前端页面编写
二、导入相关依赖包
三、创建数据库
四、构建Servlet相关类
1、实体类:Student.java
2、Servlet连接数据库父类:SQL.java
3、Student数据表操作类:StudentSQL.java
五、具体功能实现
1、页面内容的加载
2、添加学生记录
3、编辑学生记录
4、删除学生记录
六、拓展与完善
七、一点感想
八、完整源代码下载
核心思路
前端HTML页面,构成JSP页面
后端Servlet管理
后端使用JDBC连接数据库
开发环境
Dreamweaver CC 2018
Eclipse EE
MySQL 5.7
完成结果
实现学生信息管理系统,能够对学生信息进行查看、增加、修改、删除、搜索、排序等功能;
不包含任何框架,如JQurry;
一、前端页面编写
使用DW CC2018将整个系统的页面静态的编写出来。完成情况如下图所示: HTML的部分没有太大的问题,在这里也不再赘述和放置源码。 静态页面编写完成后,即可在Eclipse中新建JSP文件,将HTML代码放入。
二、导入相关依赖包
在整个系统中将会需要用到的第三方包有下列几个: 这些包都可以在Maven的第三方包下载网页下载。
三、创建数据库
在MySQL数据库中提前放入我们所需要的数据。 这里根据我的需要构建如下数据表: 并放入几行数据。
四、构建Servlet相关类
在构建服务端Servlet之前,我们需要根据java类的功能创建如下三个包:
Servlet包(用来存放Servlet类)
dao包(用来存放使用第三方库的接口或类)
entity包(实体包,用来存放实体类对象)
这样分有一个好处就是分门别类,结构比较清晰。
下面我们分别说明各个类的作用及内容
1、实体类:Student.java
我们首先建立一个实体类方便我们对数据库中每一行的数据对象进行管理。 Student类的内容可以和数据库中的字段一一对应。
public class Student {
private String id;
private String name;
private String classes;
private String phone;
private String mail;
private float grade_web;
private float grade_learning;
public Student ( String id, String name, String classes, String phone, String mail, float grade_web,
float grade_learning) {
this . id = id;
this . name = name;
this . classes = classes;
this . phone = phone;
this . mail = mail;
this . grade_web = grade_web;
this . grade_learning = grade_learning;
}
}
2、Servlet连接数据库父类:SQL.java
在这个类中我们会使用JDBC来连接数据库。
private static String dbUrl = "jdbc:mysql://localhost:3306/studentinfo?characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false" ;
private static String name;
private static String password;
private static String jdbcName = "com.mysql.jdbc.Driver" ;
private Connection connection = null;
在这其中我们先初始化以上几个变量。其中dburl中 “localhost:3306”是数据库配置时分配的端口号;“studentinfo”是我们要连接的数据库的名称。 然后我们需要初始化登录MySQL时的用户名和密码;
连接数据库:
protected Connection connectSQL ( ) {
connection = null;
try {
Class. forName ( jdbcName) ;
connection = DriverManager. getConnection ( dbUrl, name, password) ;
System. out. println ( "MySQL数据库连接成功" ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "MySQL数据库连接失败" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
System. out. println ( "数据库驱动异常" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
System. out. println ( "连接数据库时其他异常" ) ;
}
return connection;
}
关闭数据库:
protected static void closeSQL ( Connection con, PreparedStatement pstmt, ResultSet rs) {
try {
if ( rs != null)
rs. close ( ) ;
if ( pstmt != null)
pstmt. close ( ) ;
if ( con != null)
con. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "MySQL关闭失败" ) ;
}
System. out. println ( "MySQL关闭成功" ) ;
}
数据库操作:
public int executeUpdate ( String sql, Object[ ] obj) {
connection = connectSQL ( ) ;
PreparedStatement pstmt = null;
try {
pstmt = prepareStatement ( connection, sql, obj) ;
int i = pstmt. executeUpdate ( ) ;
return i;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
return 0 ;
} finally {
closeSQL ( connection, pstmt, null) ;
}
}
protected PreparedStatement prepareStatement ( Connection con, String sql, Object [ ] obj) {
PreparedStatement pstmt= null;
try {
int index= 1 ;
pstmt = con. prepareStatement ( sql) ;
if ( pstmt!= null&& obj!= null) {
for ( int i = 0 ; i < obj. length; i++ ) {
pstmt. setObject ( index, obj[ i] ) ;
index++ ;
}
}
} catch ( SQLException e1) {
e1. printStackTrace ( ) ;
}
return pstmt;
}
通过上述三个部分的内容我们已经可以连接数据库、关闭数据库和对数据库进行操作了。接下来就是针对每一个数据表进行对应需要的功能了。
3、Student数据表操作类:StudentSQL.java
这个类需要继承上面建立的SQL类,作为其子类。 因为上面这个父类其实可以看做是一个接口,并没有细化到每一个数据表的每一个操作。因此我们需要在这个StudentSQL类中实现一些我们需要的方法函数,如对Student数据表的增删查改等方法。
根据我们系统的需要我们可以构造一下几个方法:
(1)遍历数据、显示数据表中所有信息
根据SQL里的方法我们直接构造出这样的方法:
public List< Student> search ( String sql, Object. . . params) {
List< Student> list = new ArrayList < Student> ( ) ;
Connection con= this . connectSQL ( ) ;
PreparedStatement pstmt= null;
ResultSet rs= null;
try {
pstmt= this . prepareStatement ( con, sql, params) ;
rs= pstmt. executeQuery ( ) ;
while ( rs. next ( ) ) {
Student student= new Student ( rs. getString ( 1 ) , rs. getString ( 2 ) , rs. getString ( 3 ) , rs. getString ( 4 ) , rs. getString ( 5 ) , rs. getFloat ( 6 ) , rs. getFloat ( 7 ) ) ;
list. add ( student) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
closeSQL ( con, pstmt, rs) ;
}
return list;
}
public List< Student> findall ( ) {
String sql= "SELECT * FROM student" ;
return search ( sql) ;
}
接下来的其他对数据库的操作都可以根据这个来改写了
(2)条件查询、查询是否存在该条记录 在这个数据表中每一条记录有一个唯一主键:学号id,我们可以根据这唯一主键进行条件搜索,以此判断是否存在该条记录。
public boolean findone ( Student student) {
String sql= "select * from student where id=" + student. getId ( ) ;
List< Student> list= search ( sql) ;
if ( list. isEmpty ( ) ) {
System. out. println ( "不存在对应记录" ) ;
return false ;
}
else {
System. out. println ( "存在该条记录" ) ;
return true ;
}
(3)新增一条记录 在新增记录的时候需要注意的一点是,如果学号id已存在,即数据库中已存在该条记录,那么应该无法插入,因此,在插入前我们先进行一步判断,判断该记录是否存在,若不存在,则插入。
public int insert ( Student student) {
boolean existed= findone ( student) ;
if ( ! existed) {
String sql= "INSERT INTO student (id,name,class,phone,mail,grade_web,grade_learning) VALUE(?,?,?,?,?,?,?)" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) , student. getName ( ) , student. getClasses ( ) , student. getPhone ( ) , student. getMail ( ) , student. getGrade_web ( ) , student. getGrade_learning ( ) } ) ;
}
else
return 0 ;
}
(4)修改一条记录 同样在修改一条记录的时候我们也需要进行记录存在与否的判断,只有存在该条记录我们才能进行修改。
public int update ( Student student) {
boolean existed= findone ( student) ;
if ( existed) {
String sql= "update student set id=?,name=?,class=?,phone=?,mail=?,grade_web=?,grade_learning=? where id=?" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) , student. getName ( ) , student. getClasses ( ) , student. getPhone ( ) , student. getMail ( ) , student. getGrade_web ( ) , student. getGrade_learning ( ) , student. getId ( ) } ) ;
}
else
return 0 ;
}
(5)删除一条记录 与修改一条记录的思路相同,判断存在性、删除。
public int delete ( Student student) {
boolean existed= findone ( student) ;
if ( existed) {
String sql= "delete from student where id=?" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) } ) ;
}
else
return 0 ;
}
(6)条件查询、根据一个字段值进行查询 根据某一个字段和一个关键词来进行搜索,类似于上面查询记录是否存在的升级版。
public List< Student> find_condition ( String row, String condition) {
String sql = "select * from student where " + row + " = \"" + condition + "\"" ;
return search ( sql) ;
}
我对数据库不是很熟悉,不知道MySQL可不可以进行全局搜索,即不需要字段进行关键词的匹配搜索。有哪位大佬知道的,可以分享一下,一起讨论,学习。
一个与数据库相关的类就已经构造完成了。接下来就是构造Servlet类,以此作为服务端主体。接下来,我会根据具体功能结合前端JSP的内容进行分析。
五、具体功能实现
1、页面内容的加载
当页面在首次加载的时候就应该默认显示出所有记录,即当页面元素全部加载完毕之后前端需要发送一个请求给服务端,服务端根据请求内容(这里就是遍历数据库并返回所有结果)返回给客户端结果。我采用的方式是Ajax发送请求的方式。
通过调用JS里面 window.onload() 函数就可以完成加载完页面元素时的下一步操作。
window. onload = function ( ) {
var whole_page= document. getElementById ( "whole_page" ) ;
whole_page. style. width= ( window. screen. availWidth- 15 ) + "px" ;
whole_page. style. height= window. screen. availHeight+ "px" ;
requestAjax ( "show_all_student" ) ;
}
通过requestAjax函数进行Ajax请求。
Ajax请求的具体操作很简单,网上也有很多教程和例子,我就直接放上我的代码了。
var req;
function requestAjax ( param) {
var url= "ShowServlet?control=" + param;
if ( window. XMLHttpRequest) {
req = new XMLHttpRequest ( ) ;
}
else if ( window. ActiveXObject) {
req = new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
}
req. open ( "POST" , url, true ) ;
req. onreadystatechange = callback;
req. send ( null ) ;
}
在Ajax请求之后返回的内容和操作都将在callback回调函数中进行。 我们先看服务端接受ajax请求。 在上面Ajax请求中,我们可以看到url是ShowServlet ,也就是会向ShowServlet发送请求。 问号?后面的是请求所带的参数,参数以键值对的形式存在:健名=键值 ,此时我的参数为:control=show_alll_student 就可以被发送给服务端。 接下来我们还设置了请求的方式:在req.open函数中设置了以POST请求 的方式。服务器端就将在doPost()函数中接收请求。
需要注意的是:我们在传参和后面传递值得时候都需要注意一点就是 编码方式要统一,建议都采用UTF-8的编码方式进行传值,否则会出现中文乱码的情况。 首先设置编码方式: request.setCharacterEncoding(“utf-8”); response.setCharacterEncoding(“utf-8”); response.setContentType(“text/html;charset=utf-8”);
在通过getParameter方法获取传递过来的参数。
String control= request. getParameter ( "control" ) ;
List< Student> list = null;
if ( control== null) {
return ;
}
else if ( control. equals ( "show_all_student" ) )
list= studentSQL. findall ( ) ;
通过这样的方式我们就可以将我们所需要的记录保存到一个ArrayList中了,可这样的对象数组的形式我们是无法传递回客户端的。因此,我们要做出一定的改变。 一个方法就是将这些数据转化成JSON数据,再转化成JSONString,这样就可以传递JSONString了。
我们可以通过JSONArray的数据结构保存多个JSON对象。
for ( Student student: list) {
JSONObject json = new JSONObject ( ) ;
json. put ( "id" , student. getId ( ) ) ;
json. put ( "name" , student. getName ( ) ) ;
json. put ( "classes" , student. getClasses ( ) ) ;
json. put ( "phone" , student. getPhone ( ) ) ;
json. put ( "mail" , student. getMail ( ) ) ;
json. put ( "grade_web" , student. getGrade_web ( ) ) ;
json. put ( "grade_learning" , student. getGrade_learning ( ) ) ;
jsonArray. add ( json) ;
}
PrintWriter out = response. getWriter ( ) ;
out. print ( jsonArray) ;
out. flush ( ) ;
out. close ( ) ;
这样,服务端的工作就结束了,已经将值传递出去了。现在轮到客户端来接收这些数据了。
var dataspan= document. getElementById ( "data" ) ;
var data= "" ;
function callback ( ) {
if ( req. readyState == 4 && req. status == 200 ) {
var jsonArray_str = req. responseText;
data= dataspan. innerHTML;
var jsonArray = JSON . parse ( jsonArray_str) ;
for ( json in jsonArray) {
var data_one= " "+ jsonArray[ json] . id+ " "+ " "+ jsonArray[ json] . name+ " "+ " "+ jsonArray[ json] . classes+ " "+ " "+ jsonArray[ json] . phone+ " "+ " "+ jsonArray[ json] . mail+ " "+ " "+ jsonArray[ json] . grade_web+ " "+ " "+ jsonArray[ json] . grade_learning+ " ";
var tail = ' + ' οnclick="popup_window(this)"' + '>编辑 + ' οnclick="delete_note(this)"' + ' >删除 ';
data_one= ""+ data_one+ tail+ " " ;
data+= data_one;
}
dataspan. innerHTML= data;
}
}
客户端接收到这些JSONString之后又转化成原来的JSONArray,通过遍历我们就能得到我们想要的数据。 要想将这些数据按照网页的内容框架显示出来,我们还需要下面几步调整。
首先,确定我们要将数据放入到一个表格 中,表头是固定的。name我们提前写好表头:
< table id= "data" >
< tr>
< th rowspan= "2" > 学号< / th>
< th rowspan= "2" > 姓名< / th>
< th rowspan= "2" > 班级< / th>
< th rowspan= "2" > 电话< / th>
< th rowspan= "2" > 邮箱< / th>
< th colspan= "2" > 学科成绩< / th>
< th rowspan= "2" > 操作< / th>
< / tr>
< tr>
< th> Web技术< / th>
< th> 机器学习< / th>
< / tr>
< / table>
有很多种方式将数据放入到这个表格中,我采用的是直接将内容写入到表格的innerHTML中。也就是上面callback函数中,先获取了表格(id=data)的innerHTML,此时还只是表头,接下来,将数据通过data这个String一一写入;最后再放入到表格的innerHTML中。
到这里,我们的显示数据的过程就已经完成了。 如果现在我们运行客户端和服务端我们就可以看到一个初始默认显示全部记录的结果。
2、添加学生记录
添加学生记录客户端需要有所输入,这时我们采用表单的方式就会方便很多。 这里我设置了一个div来让用户填写表单,当点击添加学生按钮时,显示div,其余时刻,或div内点击取消时,隐藏div。可以看作是一个简易版的网页弹窗的形式。 只需要设置display方式就可以了。 用户就可以根据提示填写表单。最后点击确定提交表单。 在定义表单时我们就可以定义请求的地址和请求的方式:
< form class = " new_window_form" method = " get" action = " ShowServlet" >
ShowServlet就可以通过GET方式进行请求。 在服务端这边,还是一样
先设置编码方式:
request. setCharacterEncoding ( "utf-8" ) ;
response. setCharacterEncoding ( "utf-8" ) ;
response. setContentType ( "text/html;charset=utf-8" ) ;
接收参数 通过request.getParameter()方法获取参数,在这里就是表单的内容。获取到单独的一条条String内容后我们可以构造一个Student对象,把数据放入其中,方便管理和下一步的操作。
String id = request. getParameter ( "id" ) ;
String name = request. getParameter ( "name" ) ;
String classes = request. getParameter ( "class" ) ;
String phone = request. getParameter ( "phone" ) ;
String mail = request. getParameter ( "mail" ) ;
float grade_web = Float. parseFloat ( request. getParameter ( "grade_web" ) ) ;
float grade_learning = Float. parseFloat ( request. getParameter ( "grade_learning" ) ) ;
Student student = new Student ( id, name, classes, phone, mail, grade_web, grade_learning) ;
最后调用StudentSQL中的insert函数就可以插入数据库了。然后通过:
response. sendRedirect ( "index.jsp" ) ;
返回原来的index.jsp。
3、编辑学生记录
编辑和新建一样都是需要用户输入来进行操作的,因此还是通过表单的方式进行。只需要动态的方式改变表单的标题和内容就可以了,这样就只需要一个表单。 同新建不同的是,编辑时,我们需要预留原来的值在表单当中。 而我们发现,表格的每一行后面都有一个编辑,那么问题来了:如何区分用户点击的是哪个行的编辑呢? 只有确定了用户点击的是哪一行,我们才能将值赋在表单当中。
这里有两种方法提供参考:
动态赋给编辑一个id; id的值可以为整条记录或是该条记录的学生id号,但这样的方式,在弹出表单的时候还要进行一次Ajax请求来获取表单的其他值的内容。
通过兄弟结点的方式获得表格该行其他列的内容 查询相关资料后我们发现,可以通过parentNode和children来获取一个结点的父节点和子节点,这样我们就可以获取到一个结点的兄弟节点,即一个表格的一行的其他内容。
这里我采用的是第二种方法。
else {
document. getElementById ( "window_title" ) . innerHTML= "编辑一条记录" ;
document. getElementById ( "submit_btn" ) . value= "edit" ;
document. getElementById ( "id" ) . value = btn. parentNode. parentNode. children[ 0 ] . textContent;
document. getElementById ( "name" ) . value = btn. parentNode. parentNode. children[ 1 ] . textContent;
document. getElementById ( "class" ) . value = btn. parentNode. parentNode. children[ 2 ] . textContent;
document. getElementById ( "phone" ) . value = btn. parentNode. parentNode. children[ 3 ] . textContent;
document. getElementById ( "mail" ) . value = btn. parentNode. parentNode. children[ 4 ] . textContent;
document. getElementById ( "grade_web" ) . value = btn. parentNode. parentNode. children[ 5 ] . textContent;
document. getElementById ( "grade_learning" ) . value = btn. parentNode. parentNode. children[ 6 ] . textContent;
}
获取了该行数据的其他值,用户进行编辑更改,点击确定按钮提交表单。接下来的这些操作就和新建一样了。服务端接收到这些参数后,调用StudentSQL的update函数就可以修改数据库中的值了。
4、删除学生记录
删除学生记录不需要用户进行输入我们就可以不用表单的形式,而采用Ajax请求的方式进行删除。
和编辑一样,我们先获取到一个点击删除的该行的数据,因为删除在数据库操作时只需要用到一个唯一标识符:主键学号id即可,因此我们将学号id通过Ajax请求传递给服务端。
服务端接收到学号id后,直接调用StudentSQL.delete()方法就可以完成数据库的删除操作了。
**到目前为止,整个学生信息管理系统的基本功能就已经完成了。接下来就是一些拓展和完善部分**
六、拓展与完善
1、数据有效性
在新建和编辑的时候我们可以验证输入内容的有效性和合法性。如输入的学号是否为正整数纯数字、电话号码、邮箱是否为正确格式的电话号码和邮箱、输入的成绩的值是否在0~100以内,还有一个重要的内容就是输入不能为空。
验证有效性最简单的方法就是正则表达式。
function check_id ( element) {
var id_text= element. value;
var id_msg = document. getElementById ( "id_msg" ) ;
if ( id_text. length== 0 )
id_msg. innerHTML= "学号不能为空!" ;
else if ( ! ( /^[0-9]\d*$/ . test ( id_text) ) )
id_msg. innerHTML= "请输入正确的学号!" ;
else
id_msg. innerHTML= "" ;
}
function check_phone ( element) {
var phone_msg= document. getElementById ( "phone_msg" ) ;
var phone_text= element. value;
if ( ! ( /^1[3456789]\d{9}$/ . test ( phone_text) ) )
phone_msg. innerHTML= "请填写正确的手机号码!" ;
else
phone_msg. innerHTML= "" ;
}
function check_mail ( element) {
var mail_msg= document. getElementById ( "mail_msg" ) ;
var mail_text= element. value;
if ( ! ( /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/ . test ( mail_text) ) )
mail_msg. innerHTML= "请填写正确的邮箱地址!" ;
else
mail_msg. innerHTML= "" ;
}
function check_grade ( element) {
var web_msg= document. getElementById ( "web_msg" ) ;
var learning_msg= document. getElementById ( "learning_msg" ) ;
var grade= parseFloat ( element. value) ;
if ( grade< 0.0 || grade> 100 ) {
if ( element. id== "grade_web" )
web_msg. innerHTML= "请输入正确的成绩!" ;
else if ( element. id== "grade_learning" )
learning_msg. innerHTML= "请输入正确的成绩!" ;
}
else {
if ( element. id== "grade_web" )
web_msg. innerHTML= "" ;
else if ( element. id== "grade_learning" )
learning_msg. innerHTML= "" ;
}
}
在表单填写过程中,可以采用onblur 函数来调用以上这些函数,当输入框失去焦点时进行判断。
< input type = " text" autocomplete = " off" placeholder = " 学号" name = " id" id = " id" onblur = " check_id(this)" required />
2、搜索框
在编写静态页面时,我们就已经设置了一个搜索框,现在我们来实现搜索框的功能。我们这里的搜索框有两种:
数据库搜索框,即在数据库中搜索满足条件的记录,显示对应记录。
另一种是页面搜索框,即搜索页面内容,并将结果高亮显示。
下面分别实现两种搜索框。
(1)数据库搜索框 对数据库进行搜索时,因为只有一个搜索框,没有对应的字段值,无法通过一个“select”和“where”来进行搜索,因此我们在进行数据库搜索的时候就需要遍历数据库的字段名,先遍历字段的名字,在分别赋值给”where“来进行搜索。
public List< String> getColumn ( Object. . . params) {
List< String> list= new ArrayList < String> ( ) ;
String sql = "desc student" ;
Connection con= this . connectSQL ( ) ;
PreparedStatement pstmt= null;
ResultSet rs= null;
try {
pstmt= this . prepareStatement ( con, sql, params) ;
rs= pstmt. executeQuery ( ) ;
while ( rs. next ( ) ) {
String string = rs. getString ( 1 ) ;
list. add ( string) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
closeSQL ( con, pstmt, rs) ;
}
return list;
}
接下来在客户端JS中写调用的函数,进行服务端请求,采用表单,Ajax等形式都可以,我这里采用的是Ajax的形式。
搜索框点击搜索按钮调用onclick 函数,在函数中我们就可以进行Ajax请求。
function search_database ( ) {
var key = document. getElementById ( "search_key" ) . value;
if ( key== "" ) {
requestAjax ( "control=show_all_student" ) ;
return ;
}
var param = "control=search&value=" + key;
requestAjax ( param) ;
}
服务器端一样的响应请求。
else if ( control. equals ( "search" ) ) {
String key = request. getParameter ( "value" ) ;
List< String> columnList = studentSQL. getColumn ( ) ;
for ( String column: columnList) {
List< Student> array = new ArrayList < Student> ( ) ;
array = studentSQL. find_condition ( column, key) ;
list. addAll ( array) ;
}
}
这样就可以完成对一个关键词的搜索并保存到一个List中返回给客户端前端显示。
拓展: 一般来说我们在进行搜索的时候都希望能有模糊搜索的功能,在进行数据库搜索时可以进行模糊搜索。 只需要改动一点点就可以了:只需要在数据库操作类StudentSQL类中的条件搜索函数中改成利用正则表达式进行搜索就可以了。
public List< Student> find_condition ( String row, String condition) {
String sql = "select * from student where " + row + " REGEXP \"" + condition + "\"" ;
return search ( sql) ;
}
如果当我们搜索“2”时,理论上应该是显示“小花”和小刚两条记录。
但是会出现下面这种情况,原因是一条记录匹配了2次或多次,我们要把重复的记录去掉。 我们可以利用Set没有重复性的特点,将ArrayList转化为Set,来去重。 考虑到对象类型的Set集合无法去重,我们先在Student类里重写equals方法 和hashCode方法 。
@Override
public boolean equals ( Object obj) {
if ( obj == null)
return false ;
if ( this == obj)
return true ;
if ( obj instanceof Student ) {
Student student = ( Student) obj;
if ( student. getId ( ) . equals ( this . id)
&& student. getName ( ) . equals ( this . name)
&& student. getClasses ( ) . equals ( this . classes)
&& student. getPhone ( ) . equals ( this . phone)
&& student. getMail ( ) . equals ( this . mail)
&& student. getGrade_web ( ) == this . grade_web
&& student. getGrade_learning ( ) == this . grade_learning)
return true ;
}
return false ;
}
@Override
@SuppressWarnings ( "deprecation" )
public int hashCode ( ) {
Float float_web = new Float ( grade_web) ;
Float float_learning = new Float ( grade_learning) ;
return id. hashCode ( ) * name. hashCode ( ) * classes. hashCode ( ) * phone. hashCode ( ) * mail. hashCode ( ) * float_web. hashCode ( ) * float_learning. hashCode ( ) ;
}
关于为什么要重写而不能直接使用set的去重功能,具体可以参考这篇博文。
https://blog.csdn.net/lavorange/article/details/80420087
经过set去重我们就可以完后曾模糊搜索的功能了。
else if ( control. equals ( "search" ) ) {
String key = request. getParameter ( "value" ) ;
List< String> columnList = studentSQL. getColumn ( ) ;
for ( String column: columnList) {
List< Student> array = new ArrayList < Student> ( ) ;
array = studentSQL. find_condition ( column, key) ;
list. addAll ( array) ;
}
Set< Student> set = new HashSet < Student> ( list) ;
List< Student> temp_list = new ArrayList < Student> ( set) ;
list= temp_list;
}
最后向前端输出list内容就可以了。
(2)页面内容搜索框 页面内容搜索框就只包含前端的内容了,不需要进行后端的操作。在搜索框中输入关键词,能够将表格中的搜索结果高亮显示出来。
大概思路如下: 首先通过innerHTML 获取到我们要搜索的区域的所有内容(包含标签代码!!! ),然后通过split函数 将关键词两边的内容分开,然后给关键词加上style属性,再用join函数 合在一起就可以了。
但是这样做有一个弊端,就是,如果搜索的内容是某些关键词或标签(如搜索“div”、“span”)时,就会出现报错,因为你将代码标签也算作字符串的一部分了。因此要解决这个去掉标签的问题。
我也没有想到一个很好的方法,网上查到的资料有说可以使用正则表达式来去标签,鉴于当前系统只需要搜索表格内容,即网页内容不复杂,甚至说很单一,因为只有
和两种标签,所以我将 标签一同加入到搜索的关键词当中,这样就不会出现搜索内容为标签时报错的情况了。
理论上是这个样子的,因为还是不太熟悉正则表达式,暂时还没有实现出该功能。
七、一点感想
写完一整个系统,真实感受就是全栈式开发好累(其实还是自己太菜了)。学到了许多新东西,但是还是有很多地方不会的,像上面的搜索,还有其他的一些骚操作都没有。路漫漫其修远兮啊。 花了很长时间写这篇博文记录一下整个开发过程,不断回顾和反思当初一开始没有写好的地方。挺有收获的。
八、完整源代码下载
下载地址
你可能感兴趣的:(Web开发)
用 Python 撸一个 Web 服务器-第9章:项目总结
pythonweb
项目总结本教程带大家一起实现了一个TodoList程序,包含基础的增删改查功能,和用户登录认证。这也是Web开发中最常见的需求。我画了一张思维导图,帮助你从宏观的角度来概览TodoList程序,加深你对Web开发的理解。TodoList项目整体思路参考MVC设计模式。有意设计utils/目录专门用来存储一些工具方法,这些工具方法通常比较独立,尽量不从外部模块导入依赖,其他模块需要某个工具方法时从u
Golang 框架介绍
wwwenhx
golang 开发语言 后端
以下是一篇可直接发布到CSDN的关于Golang主流框架的技术文章,包含框架对比、使用场景和代码示例:---#Golang主流框架全解析:从Web开发到微服务##引言Go语言凭借其高性能和简洁语法,已成为云原生时代的宠儿。本文将全面解析Go生态中的热门框架,涵盖Web开发、微服务、ORM等领域,助你根据业务需求选择最佳技术方案。---##一、Web开发框架###1.Gin(轻量之王)**特点**:
Webpack 基础入门
懒羊羊我小弟
前端工程化 webpack rust 前端 es6 node.js
一、Webpack是什么Webpack是一款现代JavaScript应用程序的静态模块打包工具。在Web开发中,我们的项目会包含各种类型的文件,如JavaScript、CSS、图片等。Webpack可以将这些文件打包成一个或多个文件,以便在浏览器中高效加载。它就像是一个超级管家,把项目中的各种资源整理打包,让它们能更好地协同工作。二、为什么要使用Webpack代码拆分:可以将代码拆分成多个块,实现
【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(四) -> 常见组件(二) -> tabs
枫叶丹4
HarmonyOS 前端 javascript 开发语言 harmonyos 华为 华为云
目录1->创建Tabs2->设置Tabs方向3->设置样式4->显示页签索引5->场景示例1->创建Tabs在pages/index目录下的hml文件中创建一个Tabs组件。item1item2content1content2/*test.css*/.container{flex-direction:column;justify-content:center;align-items:center;
Python Web 开发:利用 FastAPI 构建 OAuth2 授权与认证系统
Switch616
Python Web python 前端 fastapi 数据库 开发语言 sql
PythonWeb开发:利用FastAPI构建OAuth2授权与认证系统目录OAuth2协议概述与工作原理FastAPI中实现OAuth2登录的基础流程在FastAPI中集成Google登录(OAuth2)使用GitHub登录与FastAPIOAuth2集成OAuth2Token的管理与认证⚙️OAuth2授权的安全性考量与最佳实践1.OAuth2协议概述与工作原理OAuth2(开放授权2.0)是
使用python开发flsak_FlaskWeb开发:基于Python的Web应用开发实战
RoseofVersailles
使用python开发flsak
本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书。•学习Flask应用的基本结构,编写示例应用;•使用必备的组件,包括模板、数据库、Web表单和电子邮件支持;•使用包和模块构建可伸缩的大型应用;•实现用户认证、角色和个人资料;•在博客网站中重用模板、分页显示列表以及使用富文本;•使用基于Flask的REST式API,在智能手机、平板电脑和其他第三
vite和react有什么区别?
因上精进,果上随缘
Javascript react.js javascript 前端
Vite和React在功能和定位上有明显的区别。Vite是一个基于浏览器原生ESimports的开发服务器和构建工具,旨在弥合当前和下一代Web开发之间的差距。它专注于为开发人员和现代Web项目提供更快、更高性能的体验。Vite的主要特性包括快速的冷启动、及时的热模块更新和真正的按需加载。它使用原生ESM作为模块系统,利用浏览器对ESM的支持,在开发时无需打包,从而实现了极速的启动速度和热模块替换
【合集】Java进阶——Java深入学习的笔记汇总 & 再论面向对象、数据结构和算法、JVM底层、多线程、类加载、
web_15534274656
面试 学习路线 阿里巴巴 java 学习 笔记
前言spring作为主流的JavaWeb开发的开源框架,是Java世界最为成功的框架,持续不断深入认识spring框架是Java程序员不变的追求;而spring的底层其实就是Java,因此,深入学习Spring和深入学习Java是硬币的正反面,两者相辅相成,相互促进。本篇博客是一篇不定期持续更新的博客,是一些Java深入学习的笔记汇总。目录前言面向对象专题再论面向对象封装和关键字private,t
C# ASP.NET的应用场景
来恩1003
C#从入门到精通 c# asp.net 数据库
.NET学习资料.NET学习资料.NET学习资料C#ASP.NET作为一种强大的Web开发框架,在众多领域都有着广泛的应用,为各类Web应用的开发提供了高效、可靠的解决方案。以下是其主要的应用场景:企业级Web应用在企业级应用开发中,C#ASP.NET凭借其卓越的性能和强大的功能,成为众多企业的首选。它能够与企业现有的系统和数据库进行无缝集成,例如与MicrosoftSQLServer数据库紧密结
Python说课内容介绍
laocooon523857886
算法 算法
一、明确课程目标1.课程目标的确定面向整个专业:Python课程作为计算机专业或相关专业中的一部分,需要对学生的编程能力、问题解决能力以及软件开发的基础技能进行培养。通过本课程,学生能够掌握Python编程的基本语法、面向对象编程、常见数据结构和算法。面向岗位:课程目标还需要结合市场需求和岗位要求。例如,数据分析、人工智能、Web开发等方向都需要具备Python编程能力。学生通过学习Python,
探索Redux:构建可预测、可测试的JavaScript应用
黎杉娜Torrent
探索Redux:构建可预测、可测试的JavaScript应用learn-redux:boom:ComprehensiveNotesforLearning(howtouse)ReduxtomanagestateinyourWeb/Mobile(React.js)Apps.项目地址:https://gitcode.com/gh_mirrors/le/learn-redux项目介绍在现代Web开发中,J
深入理解现代前端框架:Vue.js 的进阶探秘
lozhyf
工作 面试 学习 前端框架 vue.js flutter
在当今的web开发领域,前端框架如雨后春笋般涌现,而Vue.js凭借其简洁易用和强大的功能,成为了众多开发者的心头好。本文将带领大家深入探索Vue.js的一些进阶特性,帮助你将Vue应用开发提升到新的高度。一、Vue.js的响应式原理Vue.js最核心的特性之一就是其响应式系统。当数据发生变化时,Vue能够自动更新DOM,这一过程是如何实现的呢?Vue.js使用了Object.defineProp
pycharm社区版有个window和arm64版本,到底下载哪一个?还有pycharm官网
huiyuanzhenduo
pycharm ide python
首先pycharm官网是这一个。我是在2025年2月16日9:57进入的网站。如果网站还没有更新的话,那么就往下滑一下找到communityEdition,这个就是社区版了免费的。PyCharm:适用于数据科学和Web开发的PythonIDE适用于数据科学和Web开发的PythonIDE,具有智能代码补全、实时错误检查、快速修复等。https://www.jetbrains.com.cn/pych
PrimeFaces实战:IdleMonitor与Ajax的完美结合
t0_54program
ajax okhttp 前端 个人开发
在现代的Web开发中,用户交互的实时反馈是一个重要的用户体验环节。PrimeFaces作为一个强大的JavaEEUI库,提供了许多便捷的功能组件,其中之一就是IdleMonitor。通过IdleMonitor,我们可以轻松地检测用户何时处于空闲状态以及何时从空闲状态恢复活跃状态。结合Ajax技术,我们可以在用户状态变化时动态地更新页面内容,而无需重新加载整个页面。接下来,我们将通过一个简单的示例来
理解 WebGPU 中的 GPUQueue:GPU 的命令队列
ttod_qzstudio
WebGPU WebGPU
在现代图形编程中,与GPU的交互变得越来越高效和灵活,而WebGPUAPI的出现更是为Web开发者带来了强大的图形处理能力。其中,GPUQueue作为WebGPU的核心接口之一,扮演着至关重要的角色。本文将详细介绍GPUQueue的概念、功能、使用方法以及其在WebGPU架构中的地位。一、什么是GPUQueue?在WebGPU中,GPUQueue是一个命令队列接口,用于控制GPU上命令的执行。它类
JavaScript窗口大小变化事件:window.resize
星际编程喵
探索Spring的奇妙世界 javascript 前端 html vue.js react.js 前端框架 html5
1.前言在Web开发中,JavaScript是一种强大的脚本语言,它可以与HTML和CSS一起使用,为用户提供交互性和动态性的体验。其中,window.addEventListener("resize")事件是一个常用的事件之一,用于在浏览器窗口大小发生变化时触发相应的操作。本文将深入介绍这个事件的相关内容。2.简介window.resize事件是浏览器提供的一种事件,用于监听窗口大小的改变。这意
Python入门第一步:一文掌握Python3基础语法
小尤笔记
python 开发语言 爬虫 Python3 Python基础
学习Python3是编程之旅的绝佳起点,因为它语法简洁,功能强大,且广泛应用于数据科学、Web开发、自动化脚本等领域。以下是Python3的基础语法代码演示,帮助你迈出Python编程的第一步。CSDN大礼包:《2025年最新全套学习资料包》免费分享1.环境搭建安装Python:访问Python官网下载并安装最新版本的Python3。运行Python:在命令行或终端中输入python3--vers
Python Web开发记录 Day12:Django part6 用户登录
Code_流苏
# ---Python Web开发--- # Django 项目探索实验室 python 前端 django
名人说:东边日出西边雨,道是无晴却有晴。——刘禹锡《竹枝词》创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder)目录1、登录界面2、用户名密码校验3、cookie与session配置①cookie与session②配置4、登录验证5、注销登录6、图片验证码①Pillow库②图片验证码的实现7、补充:图片验证码的作用和扩展①作用②其他类型的验证码8、验证码校验在上一篇博客中我们实现
AJAX 与 ASP:现代 Web 开发的关键技术
csbysj2020
开发语言
AJAX与ASP:现代Web开发的关键技术引言在当今的Web开发领域,AJAX(AsynchronousJavaScriptandXML)和ASP(ActiveServerPages)是两项至关重要的技术。AJAX允许网页在不重新加载整个页面的情况下,与服务器交换数据和更新部分网页内容。而ASP则是一种服务器端脚本环境,用于动态生成交互性网页。本文将深入探讨AJAX和ASP的技术细节、应用场景以及
Hono.js入门指南_从零开始构建Web应用
随风九天
前端 Vue六脉神剑 前端 javascript Hono.js
1.引言项目背景与动机随着现代Web开发的快速发展,构建高效、轻量且易于维护的Web应用变得越来越重要。Hono.js作为一个轻量级的Node.js框架,以其简洁的API和高效的性能吸引了众多开发者。本文将带你从零开始,逐步构建一个功能齐全的Web应用,帮助你快速上手Hono.js。Hono.js简介及其优势Hono.js是一个极简主义的Node.js框架,专注于提供最简单的API来处理HTTP请
javascript的成熟分类:“成熟分类”之路
lizi88888
javascript 开发语言 ecmascript
JavaScript是一门广泛应用于Web前端开发的高级编程语言,具有交互性强、界面效果丰富等优点。其在Web开发中的广泛应用越来越受到业界的关注,从最初的“套壳”式编程到现在的成熟分类,JavaScript已经发生了巨大的变化。ES5ES5标准于2009年发布,是JavaScript发展的一个重要里程碑。这个版本添加了一些新的语言特性,例如:严格模式、Object.create()方法、Func
python——request
罗网_net
python python 开发语言
文章目录一、安装二、请求方式get和post1、get和post不同二、GET请求1、带参数的get请求三、post请求四、结果处理五、操作步骤一、安装安装:pipinstallrequests二、请求方式get和post在Web开发中,POST和GET是两种常见的HTTP请求方法,它们在发送数据和请求资源时扮演着关键角色。虽然它们的基本目的相同,即向服务器请求数据,但在使用方式、安全性、数据大小
【PyCharm的详细安装教程】
局外人_Jia
pycharm ide python windows linux mac
PyCharm的详细安装教程,涵盖Windows、macOS和Linux三大平台:1.下载PyCharm访问PyCharm官网。选择适合的版本:Community版:免费,适合Python基础开发。Professional版:付费,支持Web开发、数据库工具等高级功能。点击“Download”按钮下载安装包。2.Windows安装教程步骤1:运行安装程序双击下载的.exe文件。选择安装路径(默认路
大前端公共知识杂谈
黑虎含珠
# FlinkCDC
近年来,随着移动化联网浪潮的汹涌而来与浏览器性能的提升,iOS、Android、Web等前端开发技术各领风骚,大前端的概念也日渐成为某种共识。其中特别是Web开发的领域,以单页应用为代表的富客户端应用迅速流行,各种框架理念争妍斗艳,百花竞放。Web技术的蓬勃发展也催生了一系列跨端混合开发技术,希望能够结合Web的开发便捷性与原生应用的高性能性;其中以Cordova、PWA为代表的方向致力于为Web
深入解析HTTP OPTIONS请求与JAX-RS实现
t0_54program
http 网络协议 网络 个人开发
在现代的Web开发中,HTTPOPTIONS请求是一个常被忽视但非常重要的功能。它允许客户端查询服务器支持的HTTP方法列表。通过这种方式,客户端可以在发送实际请求之前了解服务器的能力。本文将通过实例详细探讨HTTPOPTIONS请求的使用,以及如何在JAX-RS中实现它。一、HTTPOPTIONS请求简介HTTPOPTIONS请求是一种用于查询服务器支持的HTTP方法的机制。当客户端发送一个OP
36.Web前端网页制作 NBA体育主题网页设计实例 大学生期末大作业 html+css+js
d321654987123
体育 前端 课程设计 html html5 javascript css jquery
目录一、前言二、网页文件三、网页效果四、代码展示1.HTML2.CSS3.JS五、更多推荐一、前言本实例以“体育”NBA为主题设计,应用html+css+js,包括图片轮翻效果、视频、表单等,12个子页面,代码简洁明了,供大家参考。【关注作者|获取更多源码(2000+个Web案例源码)|优质文章】;您的支持是我创作的动力!【点赞收藏博文】,Web开发、课程设计、毕业设计有兴趣的联系我交流分享,3Q
Tomcat服务器:Java Web应用的强大后盾
互联网动态分析
tomcat
在当今的Web开发领域,ApacheTomcat作为开源的Servlet容器和JavaServerPages(JSP)引擎,扮演着举足轻重的角色。它不仅为JavaWeb应用提供了一个稳定、高效的运行环境,还以其灵活的配置和丰富的功能赢得了广大开发者的青睐。本文将深入探讨Tomcat的基本概念、架构特点、配置与优化,以及在实际应用中的常见问题与解决方案。一、Tomcat概述Tomcat是由Apach
pythonweb项目实例-Python Web项目实战Day05 - 编写Web框架
weixin_39593427
在正式开始Web开发前,我们需要编写一个Web框架。aiohttp已经是一个Web框架了,为什么我们还需要自己封装一个?原因是从使用者的角度来说,aiohttp相对比较底层,编写一个URL的处理函数需要这么几步:第一步,编写一个用@asyncio.coroutine装饰的函数:@asyncio.coroutinedefhandle_url_xxx(request):pass第二步,传入的参数需要自
Python Flask 入门开发
胖蔡
Python 编程之道 python flask 开发语言
Python基础学习:Pyhton语法基础Python变量Python控制流Python函数与类PythonException处理Python文件操作Python日期与时间PythonSocket的使用Python模块Python魔法方法与属性Flask基础学习:Python中如何选择Web开发框架?PythonFlask入门开发如何使用virtualenv实现python环境的隔离?Python
少数人知道的 10 个神奇 CSS 选择器
前端javascript
ReactHook深入浅出CSS技巧与案例详解vue2与vue3技巧合集VueUse源码解读在Web开发中,CSS扮演着至关重要的角色,但很多开发者并没有真正发掘它的全部潜力!大多数人熟悉ID选择器、类选择器或元素选择器,甚至伪元素的使用也很常见。然而,你知道CSS其实还有许多不为人知的强大选择器吗?今天,就带你揭秘一些鲜有人知但却非常实用的CSS选择器,让你在样式控制上更上一层楼!1.属性选择器
Java 并发包之线程池和原子计数
lijingyao8206
Java计数 ThreadPool 并发包 java线程池
对于大数据量关联的业务处理逻辑,比较直接的想法就是用JDK提供的并发包去解决多线程情况下的业务数据处理。线程池可以提供很好的管理线程的方式,并且可以提高线程利用率,并发包中的原子计数在多线程的情况下可以让我们避免去写一些同步代码。
这里就先把jdk并发包中的线程池处理器ThreadPoolExecutor 以原子计数类AomicInteger 和倒数计时锁C
java编程思想 抽象类和接口
百合不是茶
java 抽象类 接口
接口c++对接口和内部类只有简介的支持,但在java中有队这些类的直接支持
1 ,抽象类 : 如果一个类包含一个或多个抽象方法,该类必须限定为抽象类(否者编译器报错)
抽象方法 : 在方法中仅有声明而没有方法体
package com.wj.Interface;
[房地产与大数据]房地产数据挖掘系统
comsci
数据挖掘
随着一个关键核心技术的突破,我们已经是独立自主的开发某些先进模块,但是要完全实现,还需要一定的时间...
所以,除了代码工作以外,我们还需要关心一下非技术领域的事件..比如说房地产
&nb
数组队列总结
沐刃青蛟
数组队列
数组队列是一种大小可以改变,类型没有定死的类似数组的工具。不过与数组相比,它更具有灵活性。因为它不但不用担心越界问题,而且因为泛型(类似c++中模板的东西)的存在而支持各种类型。
以下是数组队列的功能实现代码:
import List.Student;
public class
Oracle存储过程无法编译的解决方法
IT独行者
oracle 存储过程
今天同事修改Oracle存储过程又导致2个过程无法被编译,流程规范上的东西,Dave 这里不多说,看看怎么解决问题。
1. 查看无效对象
XEZF@xezf(qs-xezf-db1)> select object_name,object_type,status from all_objects where status='IN
重装系统之后oracle恢复
文强chu
oracle
前几天正在使用电脑,没有暂停oracle的各种服务。
突然win8.1系统奔溃,无法修复,开机时系统 提示正在搜集错误信息,然后再开机,再提示的无限循环中。
无耐我拿出系统u盘 准备重装系统,没想到竟然无法从u盘引导成功。
晚上到外面早了一家修电脑店,让人家给装了个系统,并且那哥们在我没反应过来的时候,
直接把我的c盘给格式化了 并且清理了注册表,再装系统。
然后的结果就是我的oracl
python学习二( 一些基础语法)
小桔子
pthon 基础语法
紧接着把!昨天没看继续看django 官方教程,学了下python的基本语法 与c类语言还是有些小差别:
1.ptyhon的源文件以UTF-8编码格式
2.
/ 除 结果浮点型
// 除 结果整形
% 除 取余数
* 乘
** 乘方 eg 5**2 结果是5的2次方25
_&
svn 常用命令
aichenglong
SVN 版本回退
1 svn回退版本
1)在window中选择log,根据想要回退的内容,选择revert this version或revert chanages from this version
两者的区别:
revert this version:表示回退到当前版本(该版本后的版本全部作废)
revert chanages from this versio
某小公司面试归来
alafqq
面试
先填单子,还要写笔试题,我以时间为急,拒绝了它。。时间宝贵。
老拿这些对付毕业生的东东来吓唬我。。
面试官很刁难,问了几个问题,记录下;
1,包的范围。。。public,private,protect. --悲剧了
2,hashcode方法和equals方法的区别。谁覆盖谁.结果,他说我说反了。
3,最恶心的一道题,抽象类继承抽象类吗?(察,一般它都是被继承的啊)
4,stru
动态数组的存储速度比较 集合框架
百合不是茶
集合框架
集合框架:
自定义数据结构(增删改查等)
package 数组;
/**
* 创建动态数组
* @author 百合
*
*/
public class ArrayDemo{
//定义一个数组来存放数据
String[] src = new String[0];
/**
* 增加元素加入容器
* @param s要加入容器
用JS实现一个JS对象,对象里有两个属性一个方法
bijian1013
js对象
<html>
<head>
</head>
<body>
用js代码实现一个js对象,对象里有两个属性,一个方法
</body>
<script>
var obj={a:'1234567',b:'bbbbbbbbbb',c:function(x){
探索JUnit4扩展:使用Rule
bijian1013
java 单元测试 JUnit Rule
在上一篇文章中,讨论了使用Runner扩展JUnit4的方式,即直接修改Test Runner的实现(BlockJUnit4ClassRunner)。但这种方法显然不便于灵活地添加或删除扩展功能。下面将使用JUnit4.7才开始引入的扩展方式——Rule来实现相同的扩展功能。
1. Rule
&n
[Gson一]非泛型POJO对象的反序列化
bit1129
POJO
当要将JSON数据串反序列化自身为非泛型的POJO时,使用Gson.fromJson(String, Class)方法。自身为非泛型的POJO的包括两种:
1. POJO对象不包含任何泛型的字段
2. POJO对象包含泛型字段,例如泛型集合或者泛型类
Data类 a.不是泛型类, b.Data中的集合List和Map都是泛型的 c.Data中不包含其它的POJO
 
【Kakfa五】Kafka Producer和Consumer基本使用
bit1129
kafka
0.Kafka服务器的配置
一个Broker,
一个Topic
Topic中只有一个Partition() 1. Producer:
package kafka.examples.producers;
import kafka.producer.KeyedMessage;
import kafka.javaapi.producer.Producer;
impor
lsyncd实时同步搭建指南——取代rsync+inotify
ronin47
1. 几大实时同步工具比较 1.1 inotify + rsync
最近一直在寻求生产服务服务器上的同步替代方案,原先使用的是 inotify + rsync,但随着文件数量的增大到100W+,目录下的文件列表就达20M,在网络状况不佳或者限速的情况下,变更的文件可能10来个才几M,却因此要发送的文件列表就达20M,严重减低的带宽的使用效率以及同步效率;更为要紧的是,加入inotify
java-9. 判断整数序列是不是二元查找树的后序遍历结果
bylijinnan
java
public class IsBinTreePostTraverse{
static boolean isBSTPostOrder(int[] a){
if(a==null){
return false;
}
/*1.只有一个结点时,肯定是查找树
*2.只有两个结点时,肯定是查找树。例如{5,6}对应的BST是 6 {6,5}对应的BST是
MySQL的sum函数返回的类型
bylijinnan
java spring sql mysql jdbc
今天项目切换数据库时,出错
访问数据库的代码大概是这样:
String sql = "select sum(number) as sumNumberOfOneDay from tableName";
List<Map> rows = getJdbcTemplate().queryForList(sql);
for (Map row : rows
java设计模式之单例模式
chicony
java设计模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述单例模式的:
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式的结构
单例模式的特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
饿汉式单例类
publ
javascript取当月最后一天
ctrain
JavaScript
<!--javascript取当月最后一天-->
<script language=javascript>
var current = new Date();
var year = current.getYear();
var month = current.getMonth();
showMonthLastDay(year, mont
linux tune2fs命令详解
daizj
linux tune2fs 查看系统文件块信息
一.简介:
tune2fs是调整和查看ext2/ext3文件系统的文件系统参数,Windows下面如果出现意外断电死机情况,下次开机一般都会出现系统自检。Linux系统下面也有文件系统自检,而且是可以通过tune2fs命令,自行定义自检周期及方式。
二.用法:
Usage: tune2fs [-c max_mounts_count] [-e errors_behavior] [-g grou
做有中国特色的程序员
dcj3sjt126com
程序员
从出版业说起 网络作品排到靠前的,都不会太难看,一般人不爱看某部作品也是因为不喜欢这个类型,而此人也不会全不喜欢这些网络作品。究其原因,是因为网络作品都是让人先白看的,看的好了才出了头。而纸质作品就不一定了,排行榜靠前的,有好作品,也有垃圾。 许多大牛都是写了博客,后来出了书。这些书也都不次,可能有人让为不好,是因为技术书不像小说,小说在读故事,技术书是在学知识或温习知识,有
Android:TextView属性大全
dcj3sjt126com
textview
android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web/email/phone/map/all) android:autoText 如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输
tomcat虚拟目录安装及其配置
eksliang
tomcat配置说明 tomca部署web应用 tomcat虚拟目录安装
转载请出自出处:http://eksliang.iteye.com/blog/2097184
1.-------------------------------------------tomcat 目录结构
config:存放tomcat的配置文件
temp :存放tomcat跑起来后存放临时文件用的
work : 当第一次访问应用中的jsp
浅谈:APP有哪些常被黑客利用的安全漏洞
gg163
APP
首先,说到APP的安全漏洞,身为程序猿的大家应该不陌生;如果抛开安卓自身开源的问题的话,其主要产生的原因就是开发过程中疏忽或者代码不严谨引起的。但这些责任也不能怪在程序猿头上,有时会因为BOSS时间催得紧等很多可观原因。由国内移动应用安全检测团队爱内测(ineice.com)的CTO给我们浅谈关于Android 系统的开源设计以及生态环境。
1. 应用反编译漏洞:APK 包非常容易被反编译成可读
C#根据网址生成静态页面
hvt
Web .net C# asp.net hovertree
HoverTree开源项目中HoverTreeWeb.HVTPanel的Index.aspx文件是后台管理的首页。包含生成留言板首页,以及显示用户名,退出等功能。根据网址生成页面的方法:
bool CreateHtmlFile(string url, string path)
{
//http://keleyi.com/a/bjae/3d10wfax.htm
stri
SVG 教程 (一)
天梯梦
svg
SVG 简介
SVG 是使用 XML 来描述二维图形和绘图程序的语言。 学习之前应具备的基础知识:
继续学习之前,你应该对以下内容有基本的了解:
HTML
XML 基础
如果希望首先学习这些内容,请在本站的首页选择相应的教程。 什么是SVG?
SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
SVG 用来定义用于网络的基于矢量
一个简单的java栈
luyulong
java 数据结构 栈
public class MyStack {
private long[] arr;
private int top;
public MyStack() {
arr = new long[10];
top = -1;
}
public MyStack(int maxsize) {
arr = new long[maxsize];
top
基础数据结构和算法八:Binary search
sunwinner
Algorithm Binary search
Binary search needs an ordered array so that it can use array indexing to dramatically reduce the number of compares required for each search, using the classic and venerable binary search algori
12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
刘星宇
c 面试
12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
1.gets()函数
问:请找出下面代码里的问题:
#include<stdio.h>
int main(void)
{
char buff[10];
memset(buff,0,sizeof(buff));
ITeye 7月技术图书有奖试读获奖名单公布
ITeye管理员
活动 ITeye 试读
ITeye携手人民邮电出版社图灵教育共同举办的7月技术图书有奖试读活动已圆满结束,非常感谢广大用户对本次活动的关注与参与。
7月试读活动回顾:
http://webmaster.iteye.com/blog/2092746
本次技术图书试读活动的优秀奖获奖名单及相应作品如下(优秀文章有很多,但名额有限,没获奖并不代表不优秀):
《Java性能优化权威指南》