JavaWeb——监听器
监听器简介
监听器是指专门用于在其他对象身上发生的事件或者状态改变进行监听和相应处理的对象,当被监听的对象发生变化时立即采取相应的行动。
例如我们要实现统计一个网站的在线人数,就可以在Web应用应用程序服务器上设置监听器用来监听session对象——设置一个全局变量,session创建的时候该变量加1,session销毁的时候该变量减1.(这个变量其实就是用户在线人数)。
Web监听器是Servlet规范定义的特殊类,可以监听客户端的请求和服务端的操作。监听的对象有:ServletContext、HttpSession、ServletRequest分别对应JSP9大内置对象中的application、session和request。用于监听ServletContext、HttpSession、ServletRequest等域对象的创建和销毁事件,监听域对象属性发生修改的事件。监听器对象可以在事件发生前、发生后做一些必要的处理。
监听器的主要用途
- 统计在线人数和在线用户;
- 系统启动时加载初始化信息;
- 统计网站访问量;
- 和Spring结合。
监听器的实现
- 创建一个类实现监听器接口(ServletRequestListener、ServletContextListener、HttpSessionListener);
- 在web.xml中注册该监听器(配置非常简单只需要在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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 配置监听器 -->
<listener>
<listener-class>listener.FirstListener</listener-class>
</listener> </web-app>
监听器的启动顺序:
在一个web.xml中可以注册多个Servlet监听器,监听器的加载顺序是按照web.xml文件中的顺序加载的。
如果我们在web.xml文件中同时配置了监听器、过滤器和Servlet,那么它们的优先级是:
监听器的分类
按照监听的对象,可以将监听器划分为如下:
按照监听的事件可以划分为以下3种:
一、域对象自身的创建和销毁的监听器
1.ServletContextListener
该监听器中有2个方法(两个方法中都有ServletContextEvent参数。可以通过它获得当前应用的上下文对象ServletContext):
public void contextInitialized(ServletContextEvent sce) // ServletContext创建时调用
public void contextDestroyed(ServletContextEvent sce) // ServletContext销毁时调用
这个监听器的主要用途是做一些定时器、加载一些全局属性对象、创建全局的数据库连接、加载一些缓存信息。
package listener; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class FirstListener implements ServletContextListener { public void contextInitialized(ServletContextEvent servletContextEvent) { String initParam = servletContextEvent.getServletContext().getInitParameter("initParam");
// 可以在这里通过Servlet的setAttribute()方法设置全局的属性对象,从其他地方可以获取到这个属性对象
servletContextEvent.getServletContext().setAttribute("name", "object");
System.out.println("===========contextInitialized,initParam = " + initParam); } public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("=================contextDestroyed================");
// 可以在这里关闭数据库连接
} }
FirstListener
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 配置监听器 -->
<listener>
<listener-class>listener.FirstListener</listener-class>
</listener> <!-- Servlet的初始化参数 -->
<context-param>
<param-name>initParam</param-name>
<param-value>123456</param-value>
</context-param> </web-app>
web.xml
将项目部署到Tomcat,运行:
HttpSessionListener
该监听器的主要作用是统计在线人数、记录访问日志【在后台统计访问时间、IP信息做一些统计数据】
package listener; import java.util.Date; import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("====================================");
System.out.println("session创建于" + new Date());
} public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("====================================");
System.out.println("session销毁于" + new Date());
} }
MyHttpSessionListener.java
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 注册监听器 -->
<listener>
<listener-class>listener.MyHttpSessionListener</listener-class>
</listener>
<!-- 配置session的超时为1min -->
<session-config>
<session-timeout>1</session-timeout>
</session-config> </web-app>
3.ServletRequestListener
该监听器的主要作用是:读取参数、记录访问历史。
package listener; import java.util.Date; import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener; public class MyServletRequestListener implements ServletRequestListener { public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("=================================");
System.out.println("request创建于" + new Date()); String name = servletRequestEvent.getServletRequest().getParameter("name");
System.out.println("从URL中获得参数name,name = " + name);
} public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("=================================");
System.out.println("request销毁于" + new Date()); } }
MyServletRequestListener.java
在web.xml中配置以上监听器,运行程序:
二、属性的增加或者删除的事件监听器
有3种,分别是ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener接口,在各个接口中都有attributeAdded()、attributeRemoved()和attributeReplaced()这3个方法。
分别创建3个类:
MyServletContextAttributeListener 继承自 ServletContextAttributeListener,
MyHttpSessionAttributeListener 继承自 HttpSessionAttributeListener,
MyServletRequestAttributeListener 继承自 ServletRequestAttributeListener。
并在web.xml中配置以上的3个监听器
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <listener>
<listener-class>listener.MyServletRequestAttributeListener</listener-class>
</listener>
<listener>
<listener-class>listener.MyHttpSessionAttributeListener</listener-class>
</listener>
<listener>
<listener-class>listener.MyServletContextAttributeListener</listener-class>
</listener>
</web-app>
web.xml
package listener; import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener; public class MyServletContextAttributeListener implements
ServletContextAttributeListener { public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext_attributeAdded:" + servletContextAttributeEvent.getName());
} public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext_attributeRemoved:" + servletContextAttributeEvent.getName());
} public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("ServletContext_attributeReplaced:" + servletContextAttributeEvent.getName());
} }
MyServletContextAttributeListener.java
package listener; import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener; public class MyServletRequestAttributeListener implements
ServletRequestAttributeListener { public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("ServletRequest_attributeAdded:" + servletRequestAttributeEvent.getName());
} public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("ServletRequest_attributeRemoved:"+ servletRequestAttributeEvent.getName());
} public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("ServletRequest_attributeReplaced:"+ servletRequestAttributeEvent.getName());
} }
MyServletRequestAttributeListener.java
package listener; import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent; public class MyHttpSessionAttributeListener implements
HttpSessionAttributeListener { public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("HttpSession_attributeAdded:" + httpSessionBindingEvent.getName());
} public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("HttpSession_attributeRemoved:" + httpSessionBindingEvent.getName());
} public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("HttpSession_attributeReplaced:" + httpSessionBindingEvent.getName());
} }
MyHttpSessionAttributeListener.java
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>主页</title>
</head> <body>
<h1>这是主页</h1>
<a href="init.jsp">跳转到init.jsp分别向ServletRequest、HttpSession、ServletContext中设置值</a><br />
<a href="destroy.jsp">跳转到destroy.jsp销毁向ServletRequest、HttpSession、ServletContext中设置的值</a>
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; // 初始化值【添加属性】,监听器将会执行各自的attributeAdded方法
request.setAttribute("requestName", "requestValue");
request.getSession().setAttribute("sessionName", "sessionValue");
request.getSession().getServletContext().setAttribute("contextName", "contextValue"); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>该页面用于初始化值</title>
</head> <body>
<h1>这是初始化值的界面!</h1>
<a href="init.jsp">跳转到init.jsp分别向ServletRequest、HttpSession、ServletContext中设置值</a><br />
<a href="destroy.jsp">跳转到destroy.jsp销毁向ServletRequest、HttpSession、ServletContext中设置的值</a>
</body>
</html>
init.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; // 删除属性,监听器将会执行各自的attributeRemoved方法
request.removeAttribute("requestName");
request.getSession().removeAttribute("sessionName");
request.getSession().getServletContext().removeAttribute("contextName");
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>销毁界面</title>
</head> <body>
<h1>销毁界面</h1>
<a href="init.jsp">跳转到init.jsp分别向ServletRequest、HttpSession、ServletContext中设置值</a><br />
<a href="destroy.jsp">跳转到destroy.jsp销毁向ServletRequest、HttpSession、ServletContext中设置的值</a>
</body>
</html>
destrot.jsp
三、绑定到HttpSession域中的对象的状态的事件监听器
HttpSession的状态如下图所示:
session的钝化机制
一般情况下session是保存在服务器内存的,服务器为每一个在线用户保存session对象,当在线用户很多时,session内存的开销将是非常巨大的——直接导致web服务器性能的降低。session的钝化机制就是将不经常使用的session对象序列化存储到文件系统或者是数据库中。需要使用这些session的时候进行反序列化到内存中。整个过程由服务器自动完成。
Tomcat中存在2种session钝化管理器。session钝化机制由SessionManger管理
org.apache.catalina.session.StandarManger
- 当Tomcat服务器被关闭或重启时,Tomcat服务器会将当前内存中的Session对象钝化到服务器的文件系统中;
- Web应用程序被重新加载(修改了web.xml)时,内存中的Session对象也会被钝化到服务器的文件系统中;
- 可以配置主流内存的Session对象数目,将不常使用的session对象保存到文件系统或者数据库,用的时候重新加载。
钝化后的文件的位置:Tomcat安装路径/work/Catalina/hostname/applicationname/SESSIONS.ser
默认情况下,Tomcat提供两个钝化驱动类:
org.apache.Catalina.FileStore和org.apache.Catalina.JDBCStore
在Servlet规范中提供了两个接口HttpSessionBindingListener和HttpSessionActivationListener分别对应绑定-解除绑定方法和钝化-活化方法。这两个监听器不需要在web.xml中注册。
HttpSessionBandingListener接口:
创建一个User实体类(普通的javabean)实现HttpSessionBandingListener接口。
package entity; import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener; public class User implements HttpSessionBindingListener { private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("绑定,属性名:"+ httpSessionBindingEvent.getName()); } public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("解除绑定,属性名:"+ httpSessionBindingEvent.getName()); } }
eneity.User.java
在init.jsp中向session中设置对象:
<% request.getSession().setAttribute("currentUser", new User()); %>
在destroy.jsp中销毁设置的对象:
<% request.getSession().removeAttribute("currentUser"); %>
运行结果:
接下来我们继续为以上的User类实现HttpSessionActivationListener接口和Serializable接口。
/** 活化 */
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println("活化:" + httpSessionEvent.getSource()); } /** 钝化 */
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent){
System.out.println("钝化:" + httpSessionEvent.getSource()); }
运行程序,可以发现向session中设置了User对象,在session没有过期的时候,服务器重启的时候会执行钝化方法,将当前的session保存在项目目录下的SESSIONS.ser。当服务器重启的时候会执行激活方法,将序列化为文件的session读入内存,并删除SESSIONS.ser。即:服务器重启不会丢失用户数据。
Servlet 3.0中监听器的应用
使用注解将监听器类声明为一个监听器,不需要在web.xml中注册监听器,但是这样做有一个弊端:无法设置监听器的顺序。@WebListener Annotation只有一个value属性【String类型】——用于描述该监听器。
见如下代码:
package listener; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener(value = "这是Servlet 3.0 的监听器")
public class MyServletContextListener implements ServletContextListener { @Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("============== contextDestroyed ============"); } @Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("============== contextInitialized ============"); } }
运行结果:
实战项目——统计在线用户及人数:
该项目使用J2EE6.0创建。
1. 创建一个类继承自HttpSessionListenr。并加上@WebListener Annotation。
package listener; import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MyHttpSessionListener implements HttpSessionListener { private static int userNumber = 0; // 用户在线人数 @Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
// 每创建一个session,在线人数加1
userNumber++;
// 把在线人数放入上下文环境中,便于在整个web应用中都可以获得在线人数
httpSessionEvent.getSession().getServletContext().setAttribute("userNumber", userNumber);
} @Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
userNumber--;
httpSessionEvent.getSession().getServletContext().setAttribute("userNumber", userNumber);
} }
MyHttpSessionListener.java
2.在index.jsp中显示在线人数:
当前在线人数:${userNumber}
以上程序就完成了一个简单的在线人数的统计。session并不能获取用户的IP地址,request对象可以获取ip地址。如果我们想要看到各个访客的来源IP,就必须做以下改进:
package listener; import java.util.ArrayList; import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; import util.SessionUtil; import entity.User;
@WebListener
public class MyHttpSessionListener implements HttpSessionListener { private static int userNumber = 0; // 用户在线人数 @Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
// 每创建一个session,在线人数加1
userNumber++;
// 把在线人数放入上下文环境中,便于在整个web应用中都可以获得在线人数
httpSessionEvent.getSession().getServletContext().setAttribute("userNumber", userNumber);
} @Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
userNumber--;
httpSessionEvent.getSession().getServletContext().setAttribute("userNumber", userNumber); ArrayList<User>userList = null; userList = (ArrayList<User>) httpSessionEvent.getSession().getServletContext().getAttribute("userList");//在线用户list
User user = SessionUtil.getUserBySessionId(userList, httpSessionEvent.getSession().getId());
if (user!=null) {
userList.remove(user);//在session销毁时从在线的用户列表中移除该用户
}
} }
MyHttpSessionListener.java
package listener; import java.util.ArrayList;
import java.util.Date; import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest; import util.SessionUtil; import entity.User;
@WebListener
public class MyServletRequestListener implements ServletRequestListener { private ArrayList<User>userList; //在线用户列表 @Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) { userList = (ArrayList<User>) servletRequestEvent.getServletContext().getAttribute("userList");
if (userList==null) {
userList = new ArrayList<User>();//首次用户请求的时候创建一个新的在线用户列表
} HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
String sessionId = request.getSession().getId(); // 如果当前用户没有在在线用户列表中,将其加入
if (SessionUtil.getUserBySessionId(userList, sessionId)==null) {
User user = new User();
user.setSessionId(sessionId);
user.setIp(request.getRemoteAddr());
user.setFirstAccseeTime(new Date());
userList.add(user);
}
servletRequestEvent.getServletContext().setAttribute("userList", userList);//将在线用户的列表保存到应用的上下文对象
} @Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) { } }
MyServletRequestListener.java
package util; import java.util.ArrayList; import entity.User; public class SessionUtil { /** 根据用户的sessionId从在线用户列表中找出用户 */
public static User getUserBySessionId(ArrayList<User>userList,String sessionId){ for (User user : userList) {
if (user.getSessionId().equals(sessionId)) {
return user;
}
}
return null;
} }
SessionUtil.java
package entity; import java.util.Date; public class User { private String sessionId; // sessionID
private String ip; // IP
private Date firstAccseeTime;// 第一次访问时间 public String getSessionId() {
return sessionId;
} public void setSessionId(String sessionId) {
this.sessionId = sessionId;
} public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} public Date getFirstAccseeTime() {
return firstAccseeTime;
} public void setFirstAccseeTime(Date firstAccseeTime) {
this.firstAccseeTime = firstAccseeTime;
} }
User.java
<%@page import="entity.User"%>
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>主页</title>
</head> <body>
当前在线人数:${userNumber}<br />
<%
ArrayList<User>userList =(ArrayList<User>) request.getServletContext().getAttribute("userList"); if(userList!=null){
for(User user:userList){
%>
IP:<%=user.getIp() %>,sessionID:<%=user.getSessionId() %>,第一次访问的时间:<%=user.getFirstAccseeTime() %><br />
<%
}
}
%>
</body>
</html>
index.jsp
项目地址:https://git.oschina.net/gaopengfei/CountTheOnlineUser.git
JavaWeb——监听器的更多相关文章
- JavaWeb监听器详解
1 JavaWeb监听器概述 在JavaWeb被监听的事件源为:ServletContext.HttpSession.ServletRequest,即三大域对象.有监听域对象"创建" ...
- 十四、JavaWeb监听器
JavaWeb监听器 三大组件: l Servlet l Listener l Filter Listener:监听器 初次相见:AWT 二次相见:SAX 监听器: l 它是一个接口,内容由我们来实现 ...
- Javaweb学习笔记——(二十)——————Javaweb监听器、国际化
Javaweb监听器 三大组件 *Servlet *Listener *Filter Listener:监听器 1.初次相见:A ...
- Day20 javaWeb监听器和国际化
day20 JavaWeb监听器 三大组件: Servlet Listener Filter Listener:监听器 初次相见:AWT 二次相见:SAX 监听器: 它是一个接口,内容由我们来 ...
- javaweb监听器实现与原理
参考:https://www.cnblogs.com/lxp503238/p/6678688.html https://blog.csdn.net/CPOHUI/article/details/888 ...
- JavaWEB监听器
1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对象 ...
- JavaWeb—监听器Listener
1.简介 Listener是Servlet的监听器,Servlet 监听器用于监听一些重要事件的发生,监听器对象在事情发生前.发生后可以做一些必要的处理. JavaWeb里面的listener是通过观 ...
- JAVAWEB监听器(二)
监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事 ...
- Javaweb监听器(2)
属性监听器:ServletRequestAtttributeListener/HttpSeessionAttributeListener/ServletContextAttributeListener ...
- Java-Web监听器
在WEB端实现监听实质: 实现一系列的监听接口(实现相应的接口,覆写各接口中相应的方法,在相应的事件触发的时候会执行自己的监听器中的覆写的方法,在各个方法中完成自己想要的操作,从而实现了监听) 监听- ...
随机推荐
- tomcat中server.xml配置详解(转载)(三)
转载自:https://www.cnblogs.com/starhu/p/5599773.html 一. <Engine>元素 每个Service元素只能有一个Engine元素.处理在同 ...
- html5:article与section元素
article元素 aiticle元素代表文档.页面或应用程序中独立的.完整的.可以肚子被外部引用的内容.它可以使一片博客或报刊中的文章.帖子. 一个article元素 ...
- remove '^M' in shell script
近期在windows上编辑一些shell脚本后上传到交换机框体上. 但这些shell脚本无法运行,每一行结尾都有'^M',同一时候框体上又没有dos2unix工具. 这么多脚本也不可能一行一行来改动. ...
- android源代码分析 android toast使用具体解释 toast自己定义
在安卓开发过程中.toast使我们常常使用的一个类.当我们须要向用户传达一些信息,可是不须要和用户交互时,该方式就是一种十分恰当的途径. 我们习惯了这样使用toast:Toast.makeText(C ...
- hibernate 多对多双向关联
package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax.persistenc ...
- win7配置两个tomcat(8 & 7)
背景如下: 电脑中原先tomcat版本是tomcat8,现在要再在其中另配置一个tomcat7,原先tomcat8的配的端口是8089 步骤如下: 1.官网下载tomcat7压缩包解压 2.修改D:\ ...
- PHP中文乱码的常见解决方法总结
PHP中文乱码是PHP开发中的常见问题之一.PHP中文乱码有时发生在网页本身,有些产生在于MySQL交互的过程中,有时与操作系统有关.下面进行一番总结. 一.首先是PHP网页的编码 1. php文件本 ...
- unity3d动态操作组件
利用范型,动态操作组件(添加或删除) e.AddComponent<CubeTranslate> ();//动态添加组件 Destroy (e.GetComponent<CubeTr ...
- jms、amqp、mqtt区别与联系
消息传递作为基本通信机制已经在全世界成功运用.无论是人与人.机器与人还是机器与机器之间,消息传递一直都是唯一常用的通信方式.在双方(或更多)之间交换消息有两种基本机制. 同步消息传递 异步消息传递 同 ...
- Android---Handler消息处理机制
搞Android的人都知道.android是不同意你在子线程中更新UI操作的.这主要出于线程安全方面的考虑.通常的做法是在主线程中创建一个Handler对象,在子线程中创建一个Message对象.该M ...