首页 文章 精选 留言 我的

精选列表

搜索[管理后台],共10000篇文章
优秀的个人博客,低调大师

Snowy v1.8 已发布,国内首个国密前后分离后台权限管理系统,让更多的人认识密码,使用密码

随着密码技术的使用普及,软件安全越来越重要,让更多的人认识密码,使用密码,此版本采用了国产密码算法SM2、SM3、SM4及签名验签技术,软件层面完全符合等保测评要求。技术框架与密码结合,让前后分离“密”不可分!具体更新如下: 1、【登录】SM2前端加密,后端解密 2、【登录登出日志】SM2对登录登出日志做签名完整性保护存储 3、【操作日志】SM2对操作日志做签名完整性保护存储 4、【Token】SM4(cbc模式)加密,Token不再曝光暴露 5、【用户密码】SM3完整性保护存储,登录时做完整性校验 6、【用户手机号】SM4(cbc模式)加解密使用字段脱敏 代码实现具体可看此次推送内容!

优秀的个人博客,低调大师

后台(23)——Listener

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl Listener简介 JavaWeb开发中我们有时需要监听域对象HttpServletRequest、HttpSession、ServletContext的创建与销毁及其属性变化;除此以外,有时还需要监听session对JavaBean的绑定和解绑。这些操作我们都可以用Listener来实现。 监听域对象的创建与销毁 在此涉及到三个监听器ServletContextListener、HttpSessionListener以及ServletRequestListener。 监听器的使用步骤 1、创建类,实现指定的监听器接口 2、实现接口中的方法 3、在web.xml文件中注册监听器 鉴于这三个监听器的使用非常类似,故在此以ServletContextListener为例说明其使用方式。 首先创建一个类实现ServletContextListener接口且实现其中的方法 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class TestServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext对象被创建"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext对象被销毁"); } } 然后我们在web.xml中注册该监听器即可 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <listener> <listener-class>cn.com.TestServletContextListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 监听域对象的属性变化 在此涉及到三个监听器ServletContextAttributeListener、HttpSessionAttributeListener以及ServletRequestAttributeListener 监听器的使用步骤 1、创建类,实现指定的监听器接口 2、实现接口中的方法 3、在web.xml文件中注册监听器 鉴于这三个监听器的使用非常类似,故在此以ServletRequestAttributeListener为例说明其使用方式。 首先创建一个类实现ServletRequestAttributeListener接口且实现其中的方法 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; public class TestServletRequestAttributeListener implements ServletRequestAttributeListener { public void attributeAdded(ServletRequestAttributeEvent srae) { System.out.println("ServletRequest添加属性"); } public void attributeRemoved(ServletRequestAttributeEvent srae) { System.out.println("ServletRequest移除属性"); } public void attributeReplaced(ServletRequestAttributeEvent event) { System.out.println("ServletRequest替换属性"); System.out.println(event.getName()+" "+event.getValue()); } } 然后我们在web.xml中注册该监听器即可 <listener> <listener-class>cn.com.TestServletRequestAttributeListener</listener-class> </listener> 嗯哼,我们来在index.jsp中测试该监听器 <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>测试</title> <style type="text/css"> p { font-size: 30px; font-family: 宋体; color: red; background-color: pink; } </style> </head> <body> <p>原创作者:谷哥的小弟</p> <p>博客地址:http://blog.csdn.net/lfdfhl</p> <% request.setAttribute("name", "小泽玛利亚"); request.setAttribute("name", "大泽玛利亚"); request.removeAttribute("name"); %> </body> </html> 监听session对JavaBean的绑定和解绑 可利用HttpSessionBindingListener监听session对JavaBean的绑定和解绑 使用步骤 1、创建JavaBean实现Serializable和HttpSessionBindingListener 2、实现接口中的方法 请看如下示例 我们先创建一个JavaBean /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.Serializable; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; public class Student implements Serializable,HttpSessionBindingListener { private int studentID; private String studentName; public int getStudentID() { return studentID; } public void setStudentID(int studentID) { this.studentID = studentID; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } @Override public String toString() { return "Student [studentID=" + studentID + ", studentName=" + studentName + "]"; } @Override public void valueBound(HttpSessionBindingEvent event) { System.out.println("Student对象被绑定"); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("Student对象被解绑"); } } 嗯哼,我们再在index.jsp中测试该监听器 <%@page import="cn.com.Student"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>测试</title> <style type="text/css"> p { font-size: 30px; font-family: 宋体; color: red; background-color: pink; } </style> </head> <body> <p>原创作者:谷哥的小弟</p> <p>博客地址:http://blog.csdn.net/lfdfhl</p> <% session.setAttribute("student", new Student()); %> </body> </html>

优秀的个人博客,低调大师

后台(21)——DBUtils

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl DBUtils简介 DBUtils是Apache提供的一个开源的数据库操作工具,它是对JDBC的简单封装,极大简化JDBC编码的工作量。比如:查询数据时它可以把结果转换成List,Array,Set等集合,非常便于开发人员操作 DBUtils的三个核心对象 QueryRunner类 主要用于增,删,改,查 ResultSetHandler接口 主要用于处理结果集 DBUtils类 该工具类主要用于关闭连接、装载JDBC驱动程序等等 嗯哼,我们将在后续的篇幅中重点介绍QueryRunner类和ResultSetHandler接口,请继续往下看。 QueryRunner QueryRunner类提供了两个构造方法 new QueryRunner() 如果采用该方法创建QueryRunner,那么数据库的事务可由我们自己手动控制。正因为该构造方法无参,所以在调用该对象的query、update、batch时需要传入参数Connection。 new QueryRunner(DataSource ds); 如果采用该方法创建QueryRunner,那么数据库的事务由DBUtils自动控制。正因为该构造方法传入了参数QueryRunner,所以在调用该对象的query、update、batch时无需传入参数Connection。 QueryRunner的常用方法如下: public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException 执行查询操作,在该查询中Object数组里的每个值被用来作为查询语句的置换参数。该方法会自行处理PreparedStatement和ResultSet的创建和关闭。 public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException 该方法与上面的这个方法基本一样;不同的是它不用将Connection提供给该方法 public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException 该方法与上面的两个方法基本一样,它用于执行一个不需要置换参数的查询操作。 public int update(Connection conn, String sql, Object[] params) throws SQLException 执行更新操作,在该查询中Object数组里的每个元素值被用来作为更新语句的置换参数。 public int update(Connection conn, String sql) throws SQLException 该方法与上面的这个方法基本一样,用来执行一个不需要置换参数的更新操作。 现在,我们通过一个例子来了解DBUtils的简单使用 /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test; public class TestCRUD { @Test public void testInsert() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); qr.update("insert into student(studentid,studentname) values(?,?)", 5,"吉泽暗步"); } @Test public void testUpdate() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); qr.update("update student set studentname=? where studentid=?", "明步吉泽",5); } @Test public void testDelete() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); qr.update("delete from student where studentid=?",2); } @Test public void testSelect()throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); BeanListHandler<Student> beanListHandler=new BeanListHandler<Student>(Student.class); List<Student> list = qr.query("select * from student",beanListHandler); for(Student s: list){ System.out.println(s); } } } 嗯哼,看到了吧,我们只用了很少的代码就实现了增删改查。尤其是最后一个例子中把查询结果直接转换成了List从而给开发带来了极大的方便! ResultSetHandler ResultSetHandler接口常用的实现类如下: ArrayHandler 把结果集中的第一行数据转成对象数组 ArrayListHandler 把结果集中的每一行数据都转成一个数组存放到List中 BeanHandler 将结果集中的第一行数据封装到一个对应的JavaBean实例中。 BeanListHandler 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 ColumnListHandler 将结果集中某一列的数据存放到List中 KeyedHandler(name) 将结果集中的每一行数据都封装到一个Map<列名,列值>里,再把这些map再存到一个map里,其key为指定的key。 MapHandler 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值 MapListHandler 将结果集中的每一行数据都封装到一个Map里,然后再存放到List 关于ResultSetHandler接口实现类的用法,请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.sql.SQLException; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test; public class TestResultSetHandler { @Test public void teseArrayHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); Object[] arr = qr.query("select * from student", new ArrayHandler()); for (Object o : arr) { System.out.println(o); } } @Test public void teseArrayListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); List<Object[]> query = qr.query("select * from student", new ArrayListHandler()); for (Object[] os : query) { System.out.println(os); for (Object o : os) { System.out.println(o); } System.out.println("----------"); } } @Test public void teseColumnListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); List<Object> list = qr.query("select * from student", new ColumnListHandler(1)); for (Object o : list) { System.out.println(o); } } @Test public void testKeyedHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); Map<Object,Map<String,Object>> map = qr.query("select * from student", new KeyedHandler(1)); for (Map.Entry<Object, Map<String,Object>> m : map.entrySet()) { System.out.println(m.getKey()); for (Map.Entry<String, Object> mm : m.getValue().entrySet()) { System.out.println(mm.getKey()+"\t"+mm.getValue()); } System.out.println("----------"); } } @Test public void teseMapHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); Map<String,Object> map = qr.query("select * from student where studentid=?", new MapHandler(),3); for (Map.Entry<String, Object> m : map.entrySet()) { System.out.println(m.getKey()+"\t"+m.getValue()); } } @Test public void teseMapListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); List<Map<String,Object>> list = qr.query("select * from student", new MapListHandler()); for (Map<String, Object> map : list) { for (Map.Entry<String, Object> m : map.entrySet()) { System.out.println(m.getKey()+"\t"+m.getValue()); } System.out.println("----------"); } } @Test public void teseScalarHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); Object o = qr.query("select count(*) from student", new ScalarHandler(1)); System.out.println(o.getClass().getName()); } @Test public void teseBeanHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); BeanHandler<Student> beanHandler=new BeanHandler<Student>(Student.class); Student student = qr.query("select * from student where studentid=?",beanHandler,3); System.out.println(student); } @Test public void teseBeanListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); BeanListHandler<Student> beanListHandler=new BeanListHandler<Student>(Student.class); List<Student> list = qr.query("select * from student where studentid=?", beanListHandler,3); for(Student s:list){ System.out.println(s); } } } DBUtils DBUtils类提供了关闭连接、装载JDBC驱动程序等等于资源有关的操作。 DBUtils主要方法如下: public static void close( ) throws java.sql.SQLException 用于关闭Connection、Statement和ResultSet public static void closeQuietly( ): 这一类方法不仅能关闭Connection、Statement和ResultSet,还能隐藏一些在程序中抛出的SQLException。如果不想捕捉这些异常的话,这将是一个不错的选择 public static void commitAndCloseQuietly(Connection conn): 提交并关闭连接,并且在关闭连接时不抛出SQL异常。 public static boolean loadDriver(java.lang.String driverClassName) 装载并注册JDBC驱动程序,若成功就返回true

优秀的个人博客,低调大师

后台(22)——AJAX

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl AJAX简介 AJAX(Asynchronous JavaScript And XML)不是一种新的编程语言,它指的是异步JavaScript。利用AJAX可在不重新加载整个页面的情况下与服务器通信并更新部分网页。 XMLHttpRequest AJAX 的核心是XMLHttpRequest,它是一种支持异步请求的技术。也就是说:在JavaScript中利用XMLHttpRequest可向服务器提出请求并处理响应且不阻塞用户当前操作。 XMLHttpRequest的创建 目前,市面上的大部分浏览器都支持XMLHttpRequest ,但是有的较老的浏览器比如:IE5和IE6却不支持。 所以,可以这么做: var xmlhttp; if (window.XMLHttpRequest) {//code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {//code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } XMLHttpRequest的常用方法 open(method,url,async) 建立与服务器的连接 method:指定请求方式,比如GET、POST;常用GET方式 url:请求的地址 async:是否使用异步方式请求,默认为true send(string) 将请求发送到服务器 如果是GET请求那么参数string为null,如果是POST请求那么利用string携带请求参数 setRequestHeader(header,value) 设置请求消息头;很少用到 XMLHttpRequest的常用属性 readyState readyState用于标识XMLHttpRequest的状态信息 readyState=0表示XMLHttpRequest对象未完成初始化,即刚创建。 readyState=1表示XMLHttpRequest对象开始发送请求;即调用了open方法,但还没有调用send方法,请求还没有发出 readyState=2表示XMLHttpRequest对象的请求发送完成;即send方法已经调用,数据已经提交到服务器,但没有收到任何响应 readyState=3表示XMLHttpRequest对象开始读取响应,还没有结束;即收到了响应消息头,但响应正文还没有收到 readyState=4表示XMLHttpRequest对象读取响应结束,响应消息头和响应正文都已收到 responseText 获得响应的文本内容 responseXML 获得响应的XML文档对象 status status用于标识Http请求的响应状态码 200 服务器响应正常 400 无法找到请求的资源 403 没有访问权限 404 访问的资源不存在 500 服务器内部错误 XMLHttpRequest的回调函数 每当readyState属性值改变时onreadystatechange函数就会被执行。所以我们可以在该函数中执行一些监听,比如:readyState=4而且status=200时处理服务器返回的数据 XMLHttpRequest使用示例 首先,我们写一个简单的jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/xmlhttprequest.js"></script> <title>测试AJAX</title> </head> <script type="text/javascript"> window.onload = function() { //第一步:获取XMLHttpRequest var req = getXMLHttpRequest(); //第四步:处理结果 req.onreadystatechange = function(){ if(req.readyState==4){ if(req.status==200){ alert(req.responseText); } } } //第二步:建立连接 req.open("get","${pageContext.request.contextPath }/servlet"); //第三步:发送请求 req.send(null); } </script> <body> </body> </html> 其中xmlhttprequest.js如下: function getXMLHttpRequest(){ var xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } 然后,我们再写一个非常简单的Servlet /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestAJAXServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print("Hello AJAX"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } } 运行后效果如下图所示:

优秀的个人博客,低调大师

后台(14)——HttpSession

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在之前学习HTTP时我们说:标准HTTP协议既有优点也有缺点,优点在于极大地减轻了服务器的压力,每一次请求不会造成不必要连接占用;缺点在于繁复地建立连接和断开连接,请求会传输大量重复的信息,所以随后出现了Keep-Alive、Cookie、HttpSession在某些程度上弥补了标准HTTP的缺点。在上一篇博客我们学习了Cookie,在本篇博客中我们来一起学习HttpSession HttpSession简介 与客户端技术Cookie技术不同,HttpSession是服务端技术。在WEB开发中,服务器可为用户的每个浏览器创建一个会话对象即HttpSession。默认情况下,一个浏览器独占一个HttpSession对象。因此,服务器程序可将用户数据存入用户浏览器对应的独占的HttpSession中,当用户使用浏览器访问当前应用下的其它程序时,其它程序也可以从该HttpSession中取出该用户的数据。 HttpSession的特点 HttpSession对象由服务器创建 开发人员可调用request.getSession()得到该对象 在同一个会话下多个Servlet可共享数据 比如用户访问一个含有多个Servlet的网站,那么这些Servlet可共享一个HttpSession。比如,登录后把User存放到HttpSession后其他Servlet都可以使用该对象,并且在结算Servlet时用此对象判断用户是否登录。还记得之前的ServletContext么?对于存放在ServletContext中的数据,其它用户也有权限访问,但是存放在HttpSession中的数据其他应用是无法访问的。 Cookie只能存字符串但是HttpSession可以存对象 服务器重启时会将HttpSession中的数据保存到服务器硬盘,并在重启完成后将这些数据恢复到内存中。但是请注意这些数据要实现序列化否则无法保存和还原。 HttpSession常用方法 setAttribute( ) 向HttpSession中保存数据 getAttribute( ) 从HttpSession中获取数据 removeAttribute( ) 从HttpSession中移除数据 getId( ) 返回HttpSession的唯一标识符 setMaxInactiveInterval( ) 设置session的存活时间(单位是秒),默认为30分钟 invalidate() 销毁HttpSession HttpSession使用示例 请看如下代码: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class TestHttpSession extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String NAME="name"; String JSESSIONID="JSESSIONID"; response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); HttpSession httpSession = request.getSession(); String httpSessionID=httpSession.getId(); String name=(String) httpSession.getAttribute(NAME); Cookie[] cookies = request.getCookies(); for(int i=0;cookies!=null&&i<cookies.length;i++){ Cookie cookie=cookies[i]; if (JSESSIONID.equals(cookie.getName())) { writer.println("<h4>"+"JSESSIONID="+cookie.getValue()+"</h4>"); } } if(httpSessionID!=null){ writer.println("<h4>"+"httpSessionID="+httpSessionID+"</h4>"); } if(name==null){ writer.println("<h4>"+"还没有存放数据"+"</h4>"); httpSession.setAttribute(NAME, "zxx9527"); }else{ writer.println("<h4>"+"从HttpSession中获取到数据name="+name+"</h4>"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } 代码解析如下: 为当前应用创建HttpSession,请参见代码第25行 获取HttpSession的ID,请参见代码第26行 获取名字为JSESSIONID的Cookie的值,请参见代码第32行 将数据保存至HttpSession中,请参见代码第40行 从HttpSession中取出数据,请参见代码第27行 运行后如效果如下图所示: 浅析request.getSession( ) 在刚才的示例中我们只调用了一句request.getSession()就可以开始对HttpSession的操作,那么这句代码的内部到底做了哪些事情呢? 1、获取名称为JSESSIONID的Cookie的值 2、如果没有获取到该Cookie那么就创建一个新的HttpSession且为其分配一个唯一的SessionID并且立马为浏览器生成一个名字为JSESSIONID值为sessionID的Cookie 3、如果可以获取到该Cookie,则取出该cookie的值(即HttpSession对象的SessionID),再依据此SessionID从服务器中找到与其对应的HttpSession 应对浏览器禁用Cookie的情况 通过之前的讲解我们知道:HttpSession是依赖于Cookie的,如果用户禁用了Cookie此时也就谈不上什么HttpSession了。所以,我们需要方法应对该情况的发生。 解决方案:利用response.encodeURL( )方法对网站的所有URL进行重写 执行request.getSession( ) 对sendRedirect( )涉及到的url地址进行重写 对表单的action和超链接的url进行重写 在重写URL后新的URL中就会包含JSESSIONID的值,比如JSESSIONID=30578BE1BD6600C2908607EE381BBB9B,从而将JSESSIONID携带至服务端。

优秀的个人博客,低调大师

后台(06)——JDBC

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 本文简介 本文主要介绍JDBC的基础知识及其用法。 JDBC简介 JDBC(java database connectivity)是SUN公司提供的一套利用Java语言操作数据库的标准规范。 在JDBC中定义了许多接口而数据库厂商在其数据库驱动中实现了这些接口。关于JDBC与数据库驱动的关系,请参见下图: JDBC中定义的接口(规范),各数据库厂商(比如MySQL,Oracle,DB2等)在其数据库驱动中实现了这些接口(规范)。所以,JDBC屏蔽了Java与不同数据库打交道的细节问题;假如项目原本使用的是MySQL,在某段时间后换成了Oracle,那我们基本不用去修改原来项目中的SQL语句,只需要把JDBC中MySQL的数据库驱动切换成Oracle对应的数据库驱动即可。 JDBC的核心技术点: DriverManager:用于加载驱动 Connection: 用于创建与数据库的连接 Statement: 用于操作sql语句 ResultSet: 结果集或一张虚拟表 JDBC的操作步骤: 加载驱动 创建连接 创建Statement对象 执行sql语句且返回结果 处理结果 关闭资源 嗯哼,在了解这些之后我们来看一个简单的示例,代码如下: package cn.com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.junit.Test; /** * 原创作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ public class UnitTest { @Test public void testJDBC1() { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "root"); statement = connection.createStatement(); String sql = "select * from student"; resultSet = statement.executeQuery(sql); while (resultSet.next()) { Student student = new Student(); int id = resultSet.getInt("studentid"); String name = resultSet.getString("studentname"); student.setStudentID(id); student.setStudentName(name); System.out.println(student); } } catch (Exception e) { e.printStackTrace(); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } resultSet = null; } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } statement = null; } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } connection = null; } } } } 在该示例中,利用JDBC从数据库查询数据。代码解析如下: 第一步: 加载MySQL数据库驱动,请参见代码第22行 第二步: 创建与数据的连接,请参见代码第23行 第三步: 创建用于执行SQL语句的Statement对象,请参见代码第24行 第四步: 利用Statement执行SQL语句且得到结果集,请参见代码第26行 第五步: 处理结果集,请参见代码第27-34行 第六步: 关闭资源,请参见代码第37-64行 详解JDBC常用类和接口 通过刚才的例子,我们对于JDBC的使用有了初步的了解和认知,现在此基础上详解JDBC常用的类和接口 java.sql.Drivermanager类 java.sql.Drivermanager类用于加载(注册)驱动和与数据库建立连接。 利用java.sql.Drivermanager类用于加载(注册)驱动 在此,我们采用的是: Class.forName(“com.mysql.jdbc.Driver”); 还有另外一种方式: DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 该方式不但强烈依赖数据库的驱动jar而且会导致驱动被重复注册2次。故不建议使用该方式 利用java.sql.Drivermanager类与数据库建立连接 比如,该示例中: DriverManager.getConnection(“jdbc:mysql://localhost:3306/db1”,”root”, “root”); 其中jdbc表示协议,mysql表示子协议,localhost代表IP,3306表示端口号,db1表示要连接的数据库,第一个root表示用户名,第二个root表示密码。这些值是我示例中的配置,在项目中使用时请替换这些值。 java.sql.Connection接口 java.sql.Connection是一个接口,它用于与数据库交互;各数据库驱动中均实现了该接口。java.sql.Connection最常用的操作是创建用于执行SQL语句的Statement,即: connection.createStatement(); java.sql.Statement接口 java.sql.Statement接口用于操作SQL语句并返回相应的结果集;各数据库驱动中均实现了该接口。java.sql.Statement的常用方法如下: executeQuery(String sql) 该方法用于执行select语句并根据查询语句返回结果集 executeUpdate(String sql) 该方法用于执行insert、update、delete语句并返回受影响的行数 execute(String sql) 此方法可以执行任意SQL语句。当且仅当执行select语句且有返回结果时该方法返回true, 其他情况下该方法返回false java.sql.ResultSet接口 java.sql.ResultSet用于保存执行SQL语句之后得到的结果集;各数据库驱动中均实现了该接口。 ResultSet对外暴露一个游标,该游标默认指向结果集第一行之前。ResultSet常见方法释义如下: boolean next() 将游标从当前位置向下移动一行 boolean previous() 将光标移动到此ResultSet对象的上一行。 void afterLast() 将光标移动到末尾,正好位于最后一行之后。 void beforeFirst() 将光标移动到开头,正好位于第一行之前。 Object getObject(int columnIndex); 根据序号取值,索引从1开始 Object getObject(String ColomnName); 根据列名取值 int getInt(int colIndex) 以int形式获取ResultSet结果集当前行指定列号值 int getInt(String colLabel) 以int形式获取ResultSet结果集当前行指定列名值 float getFloat(int colIndex) 以float形式获取ResultSet结果集当前行指定列号值 float getFloat(String colLabel) 以float形式获取ResultSet结果集当前行指定列名值 String getString(int colIndex) 以String形式获取ResultSet结果集当前行指定列号值 String getString(String colLabel) 以String形式获取ResultSet结果集当前行指定列名值 Date getDate(int columnIndex); 以Date形式获取ResultSet结果集当前行指定列号值 Date getDate(String columnName); 以Date形式获取ResultSet结果集当前行指定列号值 void close() 关闭ResultSet对象 在从ResultSet中获取到数据库中数据后,我们就将这些数据封装到JavaBean中;在此请注意Java的数据类型与数据库的数据类型的对应关系: 利用preparedStatement防止SQL注入 preparedStatement(预编译对象)是Statement的子类,它具有如下特点: 预先编译SQL语句 性能优异 在SQL语句中使用占位符 在此利用preparedStatement优化刚才的示例,代码如下: package cn.com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.junit.Test; /** * 原创作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ public class UnitTest { @Test public void testJDBC2() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "root"); String sql = "select * from student where studentid=? and studentname=?"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, 4); preparedStatement.setString(2, "波少野结衣"); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { Student student = new Student(); int id = resultSet.getInt("studentid"); String name = resultSet.getString("studentname"); student.setStudentID(id); student.setStudentName(name); System.out.println(student); } } catch (Exception e) { e.printStackTrace(); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } resultSet = null; } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } preparedStatement = null; } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } connection = null; } } } } 至此,关于JDBC的基础知识就介绍完了,谢谢。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册