首页 文章 精选 留言 我的

精选列表

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

后台(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>

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

后台(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 { } } 运行后效果如下图所示:

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

后台(13)——Cookie

探索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 会话 在正式进入Cookie和HttpSession的学习之前,我们先来了解一个术语:会话。 简单地说:用户打开一个浏览器后点击网页中的多个超链接访问多个web资源,访问完毕后关闭浏览器。这个过程就称之为一个会话。在会话过程中会产生一些和用户操作密切相关的数据,所以客户端或者服务端需要为每个用户保存这些数据。例如:用户点击超链接通过一个Servlet购买了几件商品,客户端或者服务端应保存这些商品信息以便于用户点结帐Servlet时,结帐Servlet得到这些已购买的商品信息从而正确地结算。 那么客户端和服务端应该怎么样保存这些用户信息呢?通常地讲,有两种方式:Cookie和HttpSession Cookie Cookie属于客户端技术。服务端把每个用户的数据以cookie的形式返回到用户的浏览器的缓存中。当用户使用浏览器再去访问服务器里的web资源时,就会将这些Cookie携带给服务端 HttpSession Session属于服务器端技术。服务端为每个用户创建一个其独享的HttpSession对象,用户在访问服务器的web资源时可把不同用户的数据放在各自对应的session中 嗯哼,在了解了关于会话的基础知识之后,我们开始进入Cookie的学习 Cookie简介 Cookie是Servlet发送浏览器的少量信息,这些信息由浏览器保存,当浏览器访问Web资源时再将其发送回服务器。一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和值(VALUE)并且名称和值都是String类型的;除此以外,它还有一些其它信息:比如注释、路径和域限定符、最大生存时间maxAge和版本号。Cookie的值可以唯一地标识客户端,因此Cookie常用于会话管理。 Servlet可通过httpServletResponse.addCookie()将字段添加到HTTP 响应头以便将Cookie发送到浏览器。浏览器支持每台Web服务器20个Cookie,合计300个,并且将每个Cookie的大小限定为4KB. 浏览器通过向HTTP请求头添加字段将Cookie返回给Servlet。服务端可用HttpServletRequest.getCookies()从请求中获取Cookie. 一个服务端可以给同一个WEB浏览器发送多个Cookie,此时,如果有两个Cookie的name一样那么后者会覆盖前者。同一个WEB浏览器也可以存储多个不同服务端提供的Cookie。请注意,发送到浏览器的Cookie在默认情况下它是一个会话级别的cookie(即Cookie被存储在浏览器的内存中)当用户退出浏览器之后即被删除。若希望浏览器将该Cookie存储在磁盘上,则需要设置Cookie的maxAge. Cookie入门示例 请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieTest1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); Cookie[] cookies = request.getCookies(); for(int i=0;cookies!=null&&i<cookies.length;i++){ Cookie cookie=cookies[i]; System.out.println(cookie.getName()+" "+cookie.getValue()); } if (cookies == null) { Cookie c1 = new Cookie("username", "tom"); Cookie c2 = new Cookie("password", "123456"); response.addCookie(c1); response.addCookie(c2); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } 代码解析如下: 生成两个Cookie,请参见代码第26-27行 利用response.addCookie()将Cookie返回给客户端,请参见代码第28-29行 利用request.getCookies()获取到浏览器携带至服务端的所有Cookie,请参见代码第20-24行 输出结果: username tom password 123456 我们再去浏览器中看看这些Cookie值,在此以谷歌浏览器为例 嗯哼,看到了吧,在此展示了Cookie的相关信息。 Cookie应用详解 cookie使用示例 在实际开发中Cookie有许多实用的地方,在此我们实现一个功能:利用Cookie记录上次访问时间 请看如下示例: /** * 本文作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ package cn.com; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieTest2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String LAST_ACCESS_TIME="time"; response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); Cookie[] cookies = request.getCookies(); for(int i=0;cookies!=null&&i<cookies.length;i++){ Cookie cookie=cookies[i]; if(LAST_ACCESS_TIME.equals(cookie.getName())){ String time = cookie.getValue(); writer.println("<h4>"+"上次访问时间:"+time+"</h4>"); System.out.println("time="+time); } } Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int date = calendar.get(Calendar.DATE); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); String time = year+"/"+(month+1)+"/"+date+" " +hour+":"+minute+":"+second; Cookie cookie = new Cookie(LAST_ACCESS_TIME, time); response.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } } 代码解析如下: 得到所有Cookie,请参见代码第27行 从所有Cookie中筛选出上次访问的时间,请参见代码第28-35行 利用Cookie将最新的访问时间返回给浏览器 运行后效果如下图所示: 我们再去浏览器中看看这些Cookie值,在此以谷歌浏览器为例 cookie的maxAge 请注意,”过期时间:浏览会话结束时”,也就是说当我们结束了本次通话(关闭浏览器)之后这些Cookie就被删除了。这是为什么呢?之前我们也说过了:Cookie在默认情况下是一个会话级别的cookie,它存在于浏览器的内存中,当用户退出浏览器之后即被删除。现在,我们希望在关闭浏览器之后再次打开浏览器时依然可以显示上次登录的时间,这就需要设置Cookie的maxAge将该Cookie存储在磁盘上。打开API我们可以看到方法cookie.setMaxAge(int expiry),默认情况下expiry的值为-1,即关闭浏览器后Cookie被删除。如果设置expiry的值为0则表示立即删除Cookie;如果设置expiry的值为正数则表示将Cookie保存到硬盘中且在expiry秒后失效。 cookie的path 请注意,”路径:/TestCookie01”,这个路径是不是觉得有点眼熟呢?哇哈,它就是我们通过request.getContextPath();获取到的应用上下文路径!所以,默认情况下通过cookie.getPath()获取到Cookie的路径正是应用的上下文路径,当然你也可以cookie.setPath()为Cookie设置path。这个path有啥用呢?我们打开官方文档看看是怎么说这个path的:在为Cookie设置path(即目录)后,Cookie对于该指定目录中的所有页面及该目录子目录中的所有页面都是可见的。哇哈,看到这里可能还是有点懵;嗯哼,我再换个方式说:如果浏览器访问的资源路径(即URI而非URL)如果是以Cookie的path开头的那么浏览器就会将该Cookie携带至服务端;否则不会携带该Cookie。举个例子:比如Cookie的path是/TestCookie01/hello;浏览器访问的是xxxx/TestCookie01/hello/haha/test.html那么浏览器就会将该Cookie携带至服务端;假如浏览器访问的是xxxx/TestCookie01/abcde/ppha/test.html那么浏览器就不会将该Cookie携带至服务端

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

后台(08)——Tomcat

探索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 本文简介 开发中常用的WEB服务器有:WebLogic、WebSphereAS、Tomcat、JbossAS等等。在本阶段的学习中我使用的是Tomcat,故在此记录Tomcat的安装和项目部署过程。 Tomcat的安装与配置 第一步:下载Tomcat 在Tomcat官网下载Tomcat,我下载的是Tomcat7对应的apache-tomcat-7.0.52.zip压缩包。 第二步:解压Tomcat 解压apache-tomcat-7.0.52.zip 第三步:配置环境变量 在环境变量中配置以下变量: 在PATH中配置tomcat的路径,比如:D:\developKits\apache-tomcat-7.0.52\bin; 配置JAVA_HOME,比如:C:\Program Files\Java\jdk1.8.0_60 配置CATALINA_HOME,比如:D:\developKits\apache-tomcat-7.0.52 第四步:启动Tomcat 第一种方式: 在D:\developKits\apache-tomcat-7.0.52\bin中双击startup.bat 第二种方式: 在DOS下执行startup 启动成功后,如下图所示: 在浏览器中输入:http://localhost:8080/ ,如下图所示: Tomcat的端口占用问题 Tomcat默认的端口号是8080,但我们时常可发现:由于端口号被占用导致Tomcat启动失败,可以这么做来解决该问题: 在DOS中执行 netstat -ano | findstr “8080” 找到占用8080端口的进程的PID 在任务管理中的详细信息中找到该PID对应的应用并将其结束 除了该方式以外,还以修改Tomcat默认的端口号。请找到D:\developKits\apache-tomcat-7.0.52\conf\server.xml中的 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 将此处的端口号修改为8081再重启Tomcat即可。 Eclipse集成Tomcat 1、在Eclipse中添加Tomcat 在Window—>Preferences—>Server—>Runtime Environments—>add添加刚才已经配置好的Tomcat 2、为项目添加index.jsp 在项目的WebContent目录下添加index.jsp文件,请参照下图: 为什么要在此添加index.jsp呢?我们来瞅瞅Tomcat的web.xml文件中的配置,请参照下图: 嗯哼,看到了吧,Tomcat把index.jsp作为了项目的首页! 3、部署项目至Tomcat 项目右键—->Run As—>Run On Server—>Tomcat7;此时,发现没有运行成功。请在Eclipse的Server视图中remove掉刚才的项目,请参照下图: 在remove操作后,请继续在Eclipse的Server视图中点击Tomcat右键执行Clean。在完成以上两步操作后,仍在Eclipse的Server视图点击Tomcat右键Open,设置Server Locations,请参照下图: 最后,请保存刚才的配置。然后再次部署项目,即可成功! 此时,我们在本地找到Tomcat的webapps文件夹,请参照下图: 嗯哼,刚才部署的项目已经保存到该文件夹下面了。 由于软件版本差异,所以在Eclipse集成Tomcat的过程中或许有些地方不太一样,这个无关紧要,也不用太纠结;毕竟主要流程是一致的。 至此,关于Tomcat就介绍完了,谢谢。

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

后台(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的基础知识就介绍完了,谢谢。

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

基于深度学习微信小程序的农作物病害识别系统

农业作为国民经济的基础性产业,其生产效率和质量直接关联着粮食安全与农民的经济收益。但农作物在生长周期中极易遭受病虫害侵扰,传统的病害识别手段过度依赖人工经验,存在识别效率低下、主观性突出、误判率偏高的问题 —— 尤其是在规模化种植场景中,人工巡检既耗费大量人力物力,又难以实现病害的早期发现与精准诊断,进而导致病害扩散蔓延,造成惨重的产量损失[1]。随着现代农业向智能化、数字化方向转型,加之计算机视觉 与深度学习技术的飞速发展,基于人工智能的病害识别方法逐渐成为破解这一痛点的核心路径。当前,YOLO 系列等目标检测算法在图像识别领域的精度与速度持续突破,为农作物病害的自动化、实时化识别提供了技术可行性,但现有相关系统普遍存在功能单一(仅支持图像检测)、用户体验欠佳(操作繁琐、识别结果展示不直观)、权限管理缺失(无法区分普通用户与管理员的需求)等问题,难以满足不同用户在实际农业生产中的多元化需求。因此,设计并开发一款功能完备、操作简便、识别精准的农作物病害识别系统,成为推动智慧农业落地应用、助力农业减少损失的迫切需求[2]。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

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

WebStorm

WebStorm

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

用户登录
用户注册