posts - 26,  comments - 14,  trackbacks - 0
  2010年11月10日


1 getCurrentSession创建的session会和绑定到当前线程,而openSession每次创建新的session。

2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭

这里getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置

    * 如果使用的是本地事务(jdbc事务)
 <property name="hibernate.current_session_context_class">thread</property>
 * 如果使用的是全局事务(jta事务)
 <property name="hibernate.current_session_context_class">jta</property> 

 getCurrentSession () 在事务结束之前使用当前的session
openSession()         每次重新建立一个新的session

在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。

使用Hibernate的大多数应用程序需要某种形式的“上下文相关的” session,特定的session在整个特定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这种“上下文”下一个定义通常 是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在3.0版本之前,使用Hibernate的程序要么采用自行编写的基于 ThreadLocal的上下文session,要么采用HibernateUtil这样的辅助类,要么采用第三方框架(比如Spring或Pico), 它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关session。

从3.0.1版本开 始,Hibernate增加了SessionFactory.getCurrentSession()方法。一开始,它假定了采用JTA事务,JTA事务 定义了当前session的范围和上下文(scope and context)。Hibernate开发团队坚信,因为有好几个独立的JTA TransactionManager实现稳定可用,不论是否被部署到一个J2EE容器中,大多数(假若不是所有的)应用程序都应该采用JTA事务管理。 基于这一点,采用JTA的上下文相关session可以满足你一切需要。

更好的是,从3.1开 始,SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,我们引入了新的扩展接口 (org.hibernate.context.CurrentSessionContext)和新的配置参数 (hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。

请参阅 org.hibernate.context.CurrentSessionContext接口的Javadoc,那里有关于它的契约的详细讨论。它定义 了单一的方法,currentSession(),特定的实现用它来负责跟踪当前的上下文session。Hibernate内置了此接口的两种实现。

org.hibernate.context.JTASessionContext - 当前session根据JTA来跟踪和界定。这和以前的仅支持JTA的方法是完全一样的。详情请参阅Javadoc。

org.hibernate.context.ThreadLocalSessionContext - 当前session通过当前执行的线程来跟踪和界定。详情也请参阅Javadoc。

这 两种实现都提供了“每数据库事务对应一个session”的编程模型,也称作每次请求一个session。Hibernate session的起始和终结由数据库事务的生存来控制。假若你采用自行编写代码来管理事务(比如,在纯粹的J2SE,或者 JTA/UserTransaction/BMT),建议你使用Hibernate Transaction API来把底层事务实现从你的代码中隐藏掉。如果你在支持CMT的EJB容器中执行,事务边界是声明式定义的,你不需要在代码中进行任何事务或 session管理操作。请参阅第 11 章 事务和并发一节来阅读更多的内容和示例代码。

hibernate.current_session_context_class 配置参数定义了应该采用哪个org.hibernate.context.CurrentSessionContext实现。注意,为了向下兼容,如果未 配置此参数,但是存在org.hibernate.transaction.TransactionManagerLookup的配 置,Hibernate会采用org.hibernate.context.JTASessionContext。一般而言,此参数的值指明了要使用的实 现类的全名,但那两个内置的实现可以使用简写,即"jta"和"thread"。

1、getCurrentSession()与openSession()的区别?

* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>

利于ThreadLocal模式管理Session
   早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序
   时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,
   而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)
   其实的功用非常简单,就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,
   而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
   ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,
   用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):
public class HibernateUtil {

public static final ThreadLocal session =new ThreadLocal();

public static final SessionFactory sessionFactory;
   static {
      try {
        sessionFactory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) {
           throw new ExceptionInInitializerError(ex);
      }    
}

     public static Session currentSession() throws HibernateException {
        Session s = session.get();
        if(s == null) {
          s = sessionFactory.openSession();
          session.set(s);
           }
         return s;
       }

    public static void closeSession() throws HibernateException {
           Session s = session.get();
        if(s != null) {
            s.close();
        }
        session.set(null);
    }
}


在这里比较了下getCurrentSession()是否是用的是同一个session...............

package com.hibernate;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateIDTest {
 private static SessionFactory sessionFactory;
 
 @BeforeClass
 public static void beforeClass() {
  try{
   sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  }catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }
 }
 @AfterClass
 public static void afterClass() {
  sessionFactory.close();
 }
 
 
 @Test
 public void testTeacherSave() {
  System.out.println("------------");
  Teacher t = new Teacher();
  t.setId(1);
  t.setName("t1");
  t.setTitle("middle");
  t.setBirthDate(new Date());
  
  Session session = sessionFactory.getCurrentSession();
  session.beginTransaction();
  session.save(t);
  session.getTransaction().commit();
  Session session2 = sessionFactory.getCurrentSession();
  
  System.out.println("比较"+(session.hashCode()==session2.hashCode()));
  
  
 }
 
}
执行之后不的到结果是  session.hashCode()==session2.hashCode()这两个只是false的,也就是说,在事务结束之后getCuttentSession 也是创建了新的session。。。。。。


openSession() 与 getCurrentSession() 有何不同和关联呢?

 

在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。

posted @ 2011-04-14 10:46 龍ぜ殘剑 阅读(5681) | 评论 (1)编辑 收藏

jfreechart主要是用来动态产生各种数据图形的,可最初使用的时候大都会碰到图片中的中文乱码或是一个小方块的情况。
仔细研究主要有以下2种原因:

1:服务器缺少中文字体,这多发生在Hp等unix操作系统上,解决的方法就是下载可用字体库到系统中,
有人也提出在Windows上产生图片在传回到Unix主机上的方法。
2:软件版本问题,jfreechart-1.0.10有人说没有问题,但jfreechart-1.0.11到13都有问题,我用的最新的jfreechart-1.0.13不做设置是有问题的。
究其原因,是它代码的内部设置的字体有问题.


其下是具体的解决办法:


public static void configFont(JFreeChart chart){  
         // 设置字体  
         Font xfont = new Font("宋体",Font.PLAIN,12) ;// X轴  
         Font yfont = new Font("宋体",Font.PLAIN,12) ;// Y轴  
         Font kfont = new Font("宋体",Font.PLAIN,12) ;// 底部  
         Font titleFont = new Font("隶书", Font.BOLD , 25) ; // 图片标题  
         CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象  
           
         // 图片标题  
         chart.setTitle(new TextTitle(chart.getTitle().getText(),titleFont));  
           
         // 底部  
         chart.getLegend().setItemFont(kfont);  
           
         // X 轴  
         CategoryAxis domainAxis = plot.getDomainAxis();     
         domainAxis.setLabelFont(xfont);// 轴标题  
         domainAxis.setTickLabelFont(xfont);// 轴数值    
         domainAxis.setTickLabelPaint(Color.BLUE) ; // 字体颜色  
         domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示   
           
         // Y 轴  
         ValueAxis rangeAxis = plot.getRangeAxis();     
         rangeAxis.setLabelFont(yfont);   
         rangeAxis.setLabelPaint(Color.BLUE) ; // 字体颜色  
         rangeAxis.setTickLabelFont(yfont);    
           
     } 
posted @ 2011-03-06 22:47 龍ぜ殘剑 阅读(544) | 评论 (0)编辑 收藏
JFreeChart项目简介

JFreeChart是开放源代码站点SourceForge.net上的一个JAVA项目,它主要用来各种各样的图表,这些图表包括:饼图、柱状图(普 通柱状图以及堆栈柱状图)、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等。这些不同式样的图表基本上可以满足目前的要求。为了减少篇幅本文主 要介绍前面三种类型的图表,读者可以触类旁通去开发其他样式的图表。




这里有点笔者在开发中遇见的问题需要注意的是:在使用Eclipse开发的时候会报一个莫名其妙的错误,错误可能指向某个类文件的第一行。遇到这样的问题一般是因为没有把Jcommon的jar包设置到项目的类路径中的缘故。具体的原因不祥。

1 饼图

对于饼图而言,数据集的获取用的不是同一个数据集类,另外饼图不支持同一个类别的项目中还有子项目这样的数据。我们只给出创建饼图的代码,至于写图表到一个文件则与柱状图一致,无需重复..

实例代码如下:

package com.dr.demo;


import java.awt.Color;
import java.awt.Font;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;


/**
 *
 * @author 詹成榜
 * @date 2010-2-25
 * @ClassName PolyLine.java
 * @Email 289153044@qq.com
 * @param 饼图
 * @param
 */

public class SalesCountServlet  {

 protected static void doGet() {
  System.out.println("图表已经建立!");
  
  CategoryDataset dataset = getDataSet();
  String fileName = "SalesCount.jpg";//文件名称
  JFreeChart chart = ChartFactory.createBarChart3D("产品销量图", // 图表标题
    "产品", // 目录轴的显示标签
    "销量", // 数值轴的显示标签
    dataset, // 数据集
    PlotOrientation.VERTICAL, // 图表方向:水平、垂直
    true, // 是否显示图例(对于简单的柱状图必须是false)
    false, // 是否生成工具
    false // 是否生成URL链接
    );
  
  configFont(chart);//设置中文格式

  FileOutputStream fos_jpg = null;
  try {
   String statImagePath = "d:";//存放文件的路径
   try {
    fos_jpg = new FileOutputStream(statImagePath+ fileName);
   } catch (FileNotFoundException e) {
    e.printStackTrace();
   }
   try {
    ChartUtilities.writeChartAsJPEG(fos_jpg, 0.5f, chart, 400, 300,null);
   } catch (IOException e) {
    e.printStackTrace();
   }
  } finally {
   try {
    fos_jpg.close();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
    
 }
  public static void configFont(JFreeChart chart){  
         // 配置字体  
         Font xfont = new Font("宋体",Font.PLAIN,12) ;// X轴  
         Font yfont = new Font("宋体",Font.PLAIN,12) ;// Y轴  
         Font kfont = new Font("宋体",Font.PLAIN,12) ;// 底部  
         Font titleFont = new Font("隶书", Font.BOLD , 25) ; // 图片标题  
         CategoryPlot plot = chart.getCategoryPlot();// 图形的绘制结构对象  
           
         // 图片标题  
         chart.setTitle(new TextTitle(chart.getTitle().getText(),titleFont));  
           
         // 底部  
         chart.getLegend().setItemFont(kfont);  
           
         // X 轴  
         CategoryAxis domainAxis = plot.getDomainAxis();     
         domainAxis.setLabelFont(xfont);// 轴标题  
         domainAxis.setTickLabelFont(xfont);// 轴数值    
         domainAxis.setTickLabelPaint(Color.BLUE) ; // 字体颜色  
         domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的label斜显示   
           
         // Y 轴  
         ValueAxis rangeAxis = plot.getRangeAxis();     
         rangeAxis.setLabelFont(yfont);   
         rangeAxis.setLabelPaint(Color.BLUE) ; // 字体颜色  
         rangeAxis.setTickLabelFont(yfont);    
           
     } 


 private static CategoryDataset getDataSet() {
  DefaultCategoryDataset dataset = new DefaultCategoryDataset();
   dataset.addValue(20, "销售图表", "苹果");
   dataset.addValue(20, "销售图表", "梨");
   dataset.addValue(30, "销售图表", "香蕉");
   dataset.addValue(40, "销售图表", "葡萄");
   dataset.addValue(50, "销售图表", "桔子");
  
  return dataset;
 }
 public static void main(String args[]){
  
  doGet();
 }
}

 

posted @ 2011-03-06 22:36 龍ぜ殘剑 阅读(415) | 评论 (3)编辑 收藏
hibernate工作原理
原理:
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory

为什么要用:
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作

3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

2. Hibernate是如何延迟加载?
1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)

2. Hibernate3 提供了属性的延迟加载功能

当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。

3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)

类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、

4. 说下Hibernate的缓存机制

1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存

2. 二级缓存:
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键数据
c) 第三方缓存的实现

5. Hibernate的查询方式
Sql、Criteria,object comptosition
Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数

6. 如何优化Hibernate?
1.使用双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3.不用一对一,用多对一取代
4.配置对象缓存,不使用集合缓存
5.一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑



spring工作原理
1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
3.DispatcherServlet请请求提交到目标Controller
4.Controller进行业务逻辑处理后,会返回一个ModelAndView
5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
6.视图对象负责渲染返回给客户端。

为什么用:
{AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务 (比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。
IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反 过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。
Spring即使一个AOP框架,也是一IOC容器。 Spring 最好的地方是它有助于您替换对象。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。}




Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

☆ Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

☆ Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

☆ Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

☆ Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

☆ Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。

IOC 和 AOP

控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。

在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。


struts工作原理

Struts工作机制?为什么要使用Struts?
工作机制:
Struts的工作流程:
在web应用启动时就会加载初始化ActionServlet,ActionServlet从
struts-config.xml文件中读取配置信息,把它们存放到各种配置对象
当ActionServlet接收到一个客户请求时,将执行如下流程.
-(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息;
-(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中;
-(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法;
-(4)如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActuibErrors对象, 就表示表单验证成功;
-(5)ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的 Action实例不存在,就先创建这个实例,然后调用Action的execute()方法;
-(6)Action的execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给 ActionForward对象指向的JSP组件;
-(7)ActionForward对象指向JSP组件生成动态网页,返回给客户;

为什么要用:
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。

基于Struts开发的应用由3类组件构成:控制器组件、模型组件、视图组件

8. Struts的validate框架是如何验证的?
在struts配置文件中配置具体的错误提示,再在FormBean中的validate()方法具体调用。

9. 说下Struts的设计模式
MVC模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的 Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用 Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。


posted @ 2011-03-06 19:59 龍ぜ殘剑 阅读(451) | 评论 (0)编辑 收藏
 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。 

        ☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

  ☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

  ☆ Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

在此 我做了个小demo 基于Spring的核心Ioc(inversion of control) 与面向切面编程AOP(Aspect Oriented Programming)。。。。。


这个例子主要完成的义务逻辑是对信息的保存,主要代码如下:

package com.dr.service;

import com.dr.DAO.ProductDAO;
import com.dr.model.Product;

public class ProductService {
 private ProductDAO productDAO;
 public void add(Product product){
  productDAO.save(product);
 }
 public ProductService(ProductDAO productDAO){
  super();
  System.out.println("ProductServic :ProductService");
  this.productDAO = productDAO;
 }
}


DAO层代码如下:


package com.dr.DAO;

import com.dr.model.Product;

 

public interface ProductDAO {
 public void save(Product product);

}





package com.dr.DAO.impl;

import com.dr.DAO.ProductDAO;
import com.dr.model.Product;

 

 

public class ProductDAOImpl implements ProductDAO {
 private String name;
 private int id;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  System.out.println("ProductDAOImple :setName");
  this.name = name;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  System.out.println("ProductDAOImpl :setId");
  this.id = id;
 }
 public void save(Product product) {
  //Hibernate
  //JDBC
  //XML
  //NetWork
  System.out.println("ProductDAOImpl :save :product saved!");
  this.toString();
 }
 public String toString(){
  System.out.println("id:"+id+"|name:"+name);
  return null;
  
 }

}



beans.xml部分代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 <bean id="p" class="com.dr.DAO.impl.ProductDAOImpl">
     <!--采用 setter()方法依赖注入-->
   <property name="name" value="11"></property>
    <property name="id" value="22"></property>
 </bean>
 <bean id="productService" class="com.dr.service.ProductService">
  <constructor-arg>
   <ref bean="p"/>
  </constructor-arg>
 </bean>
 
</beans>



测试类的代码如下所示:



package com.dr.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dr.model.Product;
import com.dr.service.ProductService;

 


//Dependency Injection  依赖注入
//Inverse of Control    控制反转
public class ProductServiceTest {

 @Test
 public void testAdd() throws Exception {
   //实例化应用上下文,Xml类路径应用上下文
  ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
  //getBean() 所得到得对象是Object类型的,所有在此必须强制转换。。。
  ProductService service = (ProductService) ctx.getBean("productService");
  
  Product product = new Product();
  product.toString();
  product.setId(20);
  product.setName("苹果");
  service.add(product);
  
 }

}


posted @ 2011-03-05 21:49 龍ぜ殘剑 阅读(2713) | 评论 (0)编辑 收藏
用Java程序   
     现在许多网站都必须统计浏览量,在此为了记录当前在线人数,我设计了一个计数器。其功能是:计数器就将自动加一,离开时就自动减一。。
这里就做了个很小的demo:
Java 代码如下:


package com.dr.demo2.servlet;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;

public class SessionCounter implements HttpSessionListener,
  ServletRequestListener {
 private static Logger log = Logger.getLogger(SessionCounter.class);
 private static final String CONTENT_TYPE = "text/html; charset=GBK";
 private static int activeSessions = 0;// 当前活动的人数
 private HttpServletRequest request;
 private static ArrayList list = new ArrayList();// 用来存放不同ip的地址

 public void init() throws ServletException {
  log.info("SessionCounter init!");

 }

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  log.info("SessionCounter doGet!");
  response.setContentType(CONTENT_TYPE);
  HttpSession session = request.getSession();
 }

 public void destroy() {
  log.info("SessionCounter destroy!");
 }

 public void requestDestroyed(ServletRequestEvent event) {
  // To change body of implemented methods use File | Settings | File
  // Templates.
  log.info("SessionCounter requestDestroyed!");
 }

 public void requestInitialized(ServletRequestEvent sre) {
  request = (HttpServletRequest) sre.getServletRequest();
  log.info("SessionCounter requestInitialized!");
 }

 public void sessionCreated(HttpSessionEvent httpSessionEvent) {
  log.info("SessionCounter sessionCreater!");
  String sessionId = httpSessionEvent.getSession().getId();
  Timestamp createTime = new Timestamp(System.currentTimeMillis());
  String loginIp = request.getRemoteAddr();
  boolean rs = true;
  if (list.size() > 0) {
   for (int i = 0; i < list.size(); i++) {
    if (loginIp.equals(list.get(i))) {
     rs = false;
    }
   }
  }
  if (rs) { // 如果队列中存在相同的IP 则SESSION不增加
   list.add(loginIp);
   log.info("ipList队列新增ip: " + loginIp);
   activeSessions++;
   log.info("新增SESSION,sessionId = " + sessionId + "; createTime = "
     + createTime + "; loginIp = " + loginIp + "; 当前总SESSION值为 "
     + activeSessions);
  }
 }

 public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
  log.info("SessionCounter sessionDestroyed!");
  String sessionId = httpSessionEvent.getSession().getId();
  Timestamp overTime = new Timestamp(System.currentTimeMillis());
  String loginIp = request.getRemoteAddr();
  if (activeSessions > 0) {
   if (list.size() > 0) {
    for (int i = 0; i < list.size(); i++) {
     if (loginIp.equals(list.get(i))) {
      list.remove(i);
      log.info("ipList队列移除ip: " + loginIp);
     }
    }
   }
   activeSessions--; // 在用户销毁的时候,从队列中踢出这个IP
   log.info("销毁SESSION,sessionId = " + sessionId + "; overTime = "
     + overTime + "; loginIp = " + loginIp + "; 当前总SESSION值为 "
     + activeSessions);
  }
 }

 public static int getActiveSessions() {
  log.info("SessionCounter getActiveSessions!");
  return activeSessions;
 }

 public void setActiveSessions(int i) {
  log.info("SessionCounter setActiveSessions!");
  activeSessions = i;
 }

}

jsp  部分代码


<%@ page language="java" import="java.util.*" pageEncoding="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>My JSP 'online.jsp' starting page</title>
   
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">   
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->

  </head>
 
  <body>
    <%@   page   import= "com.dr.demo2.servlet.SessionCounter"   %>  
 在线: <%=  SessionCounter.getActiveSessions()   %>人 
  </body>
</html>

启动tomcat ,在浏览器中输入:http://127.0.0.1:8080/OnlineCount/online.jsp

执行效果如下:

 

posted @ 2011-03-04 09:12 龍ぜ殘剑 阅读(1125) | 评论 (0)编辑 收藏
            首先我 用一种比较简单的方法,做了个小小的demo,但是这种方法用的的是Spring 框架来完成的,因为使用这种方法是一种比较实用的方法,由于很多的代码被Spring 封装在最底层。。具体的源代码如下:
Java 代码:


 import org.springframework.context.ApplicationContext;  
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
    import org.springframework.mail.SimpleMailMessage;  
    import org.springframework.mail.javamail.JavaMailSender;  
    
    public class Main {  
     
        /** 
        * @param args 
       */ 
        public static void main(String[] args) {  
         // TODO Auto-generated method stub   
           ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");  
          JavaMailSender mailSender= (JavaMailSender) context.getBean("mailSender");  
            SimpleMailMessage mail = new SimpleMailMessage();  
          mail.setFrom("avasd@126.com");  
            mail.setTo("abcd@gmail.com");  
          mail.setSubject(" 测试Mail 程序");  
          mail.setText("这里是发送的内容");  
           mailSender.send(mail);   
        }  
     
    } 


配置文件中的主要代码如下:
Spring-Mail.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
     <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
        <property name="host" value="smtp.126.com" /> 
        <property name="port" value="25" /> 
        <property name="username" value="avasd@126.com" /> 
        <property name="password" value="你的密码" /> 
        <property name="javaMailProperties"> 
            <props> 
                <prop key="mail.smtp.auth">true</prop> 
            </props> 
        </property> 
    </bean>
 

 
</beans>

在此用纯Java代码做了个小demo来发送电子邮件:

package com.cmcc.mail;
/**  
* 发送邮件需要使用的基本信息  
*/   
import java.util.Properties;   
public class MailSenderInfo {   
    // 发送邮件的服务器的IP和端口   
    private String mailServerHost;   
    private String mailServerPort = "25";   
    // 邮件发送者的地址   
    private String fromAddress;   
    // 邮件接收者的地址   
    private String toAddress;   
    // 登陆邮件发送服务器的用户名和密码   
    private String userName;   
    private String password;   
    // 是否需要身份验证   
    private boolean validate = false;   
    // 邮件主题   
    private String subject;   
    // 邮件的文本内容   
    private String content;   
    // 邮件附件的文件名   
    private String[] attachFileNames;     
    /**  
      * 获得邮件会话属性  
      */   
    public Properties getProperties(){   
      Properties p = new Properties();   
      p.put("mail.smtp.host", this.mailServerHost);   
      p.put("mail.smtp.port", this.mailServerPort);   
      p.put("mail.smtp.auth", validate ? "true" : "false");   
      return p;   
    }   
    public String getMailServerHost() {   
      return mailServerHost;   
    }   
    public void setMailServerHost(String mailServerHost) {   
      this.mailServerHost = mailServerHost;   
    }  
    public String getMailServerPort() {   
      return mailServerPort;   
    }  
    public void setMailServerPort(String mailServerPort) {   
      this.mailServerPort = mailServerPort;   
    }  
    public boolean isValidate() {   
      return validate;   
    }  
    public void setValidate(boolean validate) {   
      this.validate = validate;   
    }  
    public String[] getAttachFileNames() {   
      return attachFileNames;   
    }  
    public void setAttachFileNames(String[] fileNames) {   
      this.attachFileNames = fileNames;   
    }  
    public String getFromAddress() {   
      return fromAddress;   
    }   
    public void setFromAddress(String fromAddress) {   
      this.fromAddress = fromAddress;   
    }  
    public String getPassword() {   
      return password;   
    }  
    public void setPassword(String password) {   
      this.password = password;   
    }  
    public String getToAddress() {   
      return toAddress;   
    }   
    public void setToAddress(String toAddress) {   
      this.toAddress = toAddress;   
    }   
    public String getUserName() {   
      return userName;   
    }  
    public void setUserName(String userName) {   
      this.userName = userName;   
    }  
    public String getSubject() {   
      return subject;   
    }  
    public void setSubject(String subject) {   
      this.subject = subject;   
    }  
    public String getContent() {   
      return content;   
    }  
    public void setContent(String textContent) {   
      this.content = textContent;   
    }   
}  

 

package com.cmcc.mail;
import java.util.Date;   
import java.util.Properties;  
import javax.mail.Address;   
import javax.mail.BodyPart;   
import javax.mail.Message;   
import javax.mail.MessagingException;   
import javax.mail.Multipart;   
import javax.mail.Session;   
import javax.mail.Transport;   
import javax.mail.internet.InternetAddress;   
import javax.mail.internet.MimeBodyPart;   
import javax.mail.internet.MimeMessage;   
import javax.mail.internet.MimeMultipart;   
 
/**  
* 简单邮件(不带附件的邮件)发送器  
*/   
public class SimpleMailSender  {   
/**  
  * 以文本格式发送邮件  
  * @param mailInfo 待发送的邮件的信息  
  */   
    public boolean sendTextMail(MailSenderInfo mailInfo) {   
      // 判断是否需要身份认证   
      MyAuthenticator authenticator = null;   
      Properties pro = mailInfo.getProperties();  
      if (mailInfo.isValidate()) {   
      // 如果需要身份认证,则创建一个密码验证器   
        authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());   
      }  
      // 根据邮件会话属性和密码验证器构造一个发送邮件的session   
      Session sendMailSession = Session.getDefaultInstance(pro,authenticator);   
      try {   
      // 根据session创建一个邮件消息   
      Message mailMessage = new MimeMessage(sendMailSession);   
      // 创建邮件发送者地址   
      Address from = new InternetAddress(mailInfo.getFromAddress());   
      // 设置邮件消息的发送者   
      mailMessage.setFrom(from);   
      // 创建邮件的接收者地址,并设置到邮件消息中   
      Address to = new InternetAddress(mailInfo.getToAddress());   
      mailMessage.setRecipient(Message.RecipientType.TO,to);   
      // 设置邮件消息的主题   
      mailMessage.setSubject(mailInfo.getSubject());   
      // 设置邮件消息发送的时间   
      mailMessage.setSentDate(new Date());   
      // 设置邮件消息的主要内容   
      String mailContent = mailInfo.getContent();   
      mailMessage.setText(mailContent);   
      // 发送邮件   
      Transport.send(mailMessage);  
      return true;   
      } catch (MessagingException ex) {   
          ex.printStackTrace();   
      }   
      return false;   
    }   
      
    /**  
      * 以HTML格式发送邮件  
      * @param mailInfo 待发送的邮件信息  
      */   
    public static boolean sendHtmlMail(MailSenderInfo mailInfo){   
      // 判断是否需要身份认证   
      MyAuthenticator authenticator = null;  
      Properties pro = mailInfo.getProperties();  
      //如果需要身份认证,则创建一个密码验证器    
      if (mailInfo.isValidate()) {   
        authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());  
      }   
      // 根据邮件会话属性和密码验证器构造一个发送邮件的session   
      Session sendMailSession = Session.getDefaultInstance(pro,authenticator);   
      try {   
      // 根据session创建一个邮件消息   
      Message mailMessage = new MimeMessage(sendMailSession);   
      // 创建邮件发送者地址   
      Address from = new InternetAddress(mailInfo.getFromAddress());   
      // 设置邮件消息的发送者   
      mailMessage.setFrom(from);   
      // 创建邮件的接收者地址,并设置到邮件消息中   
      Address to = new InternetAddress(mailInfo.getToAddress());   
      // Message.RecipientType.TO属性表示接收者的类型为TO   
      mailMessage.setRecipient(Message.RecipientType.TO,to);   
      // 设置邮件消息的主题   
      mailMessage.setSubject(mailInfo.getSubject());   
      // 设置邮件消息发送的时间   
      mailMessage.setSentDate(new Date());   
      // MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象   
      Multipart mainPart = new MimeMultipart();   
      // 创建一个包含HTML内容的MimeBodyPart   
      BodyPart html = new MimeBodyPart();   
      // 设置HTML内容   
      html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");   
      mainPart.addBodyPart(html);   
      // 将MiniMultipart对象设置为邮件内容   
      mailMessage.setContent(mainPart);   
      // 发送邮件   
      Transport.send(mailMessage);   
      return true;   
      } catch (MessagingException ex) {   
          ex.printStackTrace();   
      }   
      return false;   
    }   
}  

 


测试程序如下:

package com.cmcc.mail;
/*****************************************************
 *
 * @author 詹成榜 *
 * @since 2011-3-3 *
 *****************************************************/
public class TestMail {

 public static void main(String[] args){  
        //这个类主要是设置邮件  
       MailSenderInfo mailInfo = new MailSenderInfo();   
       mailInfo.setMailServerHost("smtp.126.com");   
       mailInfo.setMailServerPort("25");   
       mailInfo.setValidate(true);   
       mailInfo.setUserName("邮箱号@126.com");   
       mailInfo.setPassword("邮箱密码");//您的邮箱密码   
       mailInfo.setFromAddress("good_hans@126.com");   
       mailInfo.setToAddress("656426515@qq.com");  
       mailInfo.setSubject("计算中心北调课通知单");
        
       String content = "";
       String header = "尊敬的"+"aa 老师:\n"+
         "您好!\n"+
         "这是一封计算中心(北)智能排课平台自动给您发送的机房课程通知单,请您按照下表的相应的时间通知学生到相应的机房上课\n"+
         "谢谢您的支持,您的满意是我们计算中心最大的快乐!\n"+
         "如果您对课表有任何疑问,请您拨打0315-2792027\n";
        
        
         content += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"+
         
                 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
           "<head>\n" +
           "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n" +
//           "<!--[if IE]><link href='/css/fkie.css' rel='stylesheet' type='text/css' media='all' /><![endif]-->\n" +
           "<style type=\"text/css\">\n" +
           "<!--\n"+  
           "html{border:0;height:100%;border:0;}\n" +
           "body{margin:0;padding:0;height:100%;font:12px/120% Arial, Helvetica, sans-serif; text-align:left;}\n" +
           "#main{ padding:15px 25px 15px 10px;}\n" +
           ".tables{ background:#b2bac5; width:100%; margin:1px 0;}\n"+     
           ".tables caption{background:#e5e8ed; padding:1px 0 0 0; _border-bottom:solid 3px #fff; height:26px;}\n"+
           ".tables th{text-align:center;background:#eef7e2; color:#016bb7; font-weight: normal; line-height:22px;}\n"+
           ".tables tr{ background:#fff;}\n"+
           ".tables tr td{line-height:22px;}\n"+
           ".area-contrl{background:#e5e8ed; padding:1px 0 0 0; _border-bottom:solid 3px #fff; height:26px;}\n" +
           "-->\n"+ 
           "</style>\n" +
           "</head>\n" +
           "<body>\n" +
           "<div id=\"main\">\n" +
           "<div class=\"area-contrl\">\n" +
           "<table class='tables' border='0' cellpadding='3' cellspacing='1'><tr><th width='35'>周次</th><th width='35'>星期</th><th width='35'>讲次</th><th width='180'>机房</th><th width='50'>人数</th><th width='100'>任课教师</th><th width='200'>班级</th><th width='300'>课程名称</th></tr>\n"
                      
                    +"<tr><td align='center'>aaa</td><td align='center'>bbb</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>eee</td><td align='center'>fff</td></tr>\n"
         +"<tr><td align='center'>aaa</td><td align='center'>bbb</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>eee</td><td align='center'>fff</td></tr>\n"
         +"<tr><td align='center'>aaa</td><td align='center'>bbb</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>eee</td><td align='center'>fff</td></tr>\n"
         +"<tr><td align='center'>aaa</td><td align='center'>bbb</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>ccc</td><td align='center'>ddd</td><td align='center'>eee</td><td align='center'>fff</td></tr>";
        
         content += "</table></div></div></body></html>";
         System.out.println(content);

        
         mailInfo.setContent(content);
         //这个类主要来发送邮件  
         SimpleMailSender sms = new SimpleMailSender();  
//         sms.sendTextMail(mailInfo);//发送文体格式   
         sms.sendHtmlMail(mailInfo);//发送html格式  
   } 
}


 

posted @ 2011-03-03 13:47 龍ぜ殘剑 阅读(1648) | 评论 (0)编辑 收藏

jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。

废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对jQuery.ajax()进行封装以方便我们使用的方法,当然,如果要处理复杂的逻辑,还是需要用到jQuery.ajax()的(这个后面会说到).

1. load( url, [data], [callback] ) :载入远程 HTML 文件代码并插入至 DOM 中。

url (String) : 请求的HTML页的URL地址。

data (Map) : (可选参数) 发送至服务器的 key/value 数据。

callback (Callback) : (可选参数) 请求完成时(不需要是success的)的回调函数。

这个方法默认使用 GET 方式来传递的,如果[data]参数有传递数据进去,就会自动转换为POST方式的。jQuery 1.2 中,可以指定选择符,来筛选载入的 HTML 文档,DOM 中将仅插入筛选出的 HTML 代码。语法形如 "url #some > selector"。

这个方法可以很方便的动态加载一些HTML文件,例如表单。


2. jQuery.get( url, [data], [callback] ):使用GET方式来进行异步请求

参数:

url (String) :  发送请求的URL地址.

data (Map) : (可选) 要发送给服务器的数据,以 Key/value 的键值对形式表示,会做为QueryString附加到请求URL中。

callback (Function) : (可选) 载入成功时回调函数(只有当Response的返回状态是success才是调用该方法)。

 

 

 

这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。示例代码:

		$.get("./Ajax.aspx", {Action:"get",Name:"lulu"}, function (data, textStatus){
//返回的 data 可以是 xmlDoc, jsonObj, html, text, 等等.
this; // 在这里this指向的是Ajax请求的选项配置信息,请参考下图
alert(data);
//alert(textStatus);//请求状态:success,error等等。
当然这里捕捉不到error,因为error的时候根本不会运行该回调函数
//alert(this); });
示例代码:

$.getJSON("servlet/TableServlet?flag=query", "", function(response){
        $.each(response,function(i){
         sel.src.add({id: response[i].id, name: response[i].name, address: response[i].address});
        })
       sel.render();
      });
    });

下面我做了一个 利用jQuery Ajax 做了以小小的Demo;

其中java 部分主要代码:

package com.bx.web.action;

 

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;

import com.bx.dao.impl.HibernateUserDAO;
import com.bx.hibernate.User;

public class TableServlet extends HttpServlet {

 
 /**
  *
  */
 private static final long serialVersionUID = 5469871499359894890L;

 User user=new User();
 
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  this.doPost(request, response);
 }

 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  String flag=request.getParameter("flag");
  if(flag!=null&&"flag".equals("flag")){
   query(request,response);
  }
 }

 public void query(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
  HibernateUserDAO test=new HibernateUserDAO();
  List<User> list = test.getUserList();
  
  for(User userlist:list){
   System.out.println("Table UserName+++"+userlist.getName()+
   "......Hibernate Dbconfig....User.Address"+userlist.getAddress());
  }
  
  JSONArray jr=JSONArray.fromObject(list);
  String jsonUser=jr.toString();
  PrintWriter out = response.getWriter();
  out.print(jsonUser);
  out.flush();
  out.close();
 }
}

jsp中的代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>tabledemo</title>
    <link href="css/style.css" type="text/css" rel="stylesheet"/>
    <script src="scripts/jquery.js" type="text/javascript"></script>
    <script src="scripts/PagerView.js" type="text/javascript"></script>
    <script src="scripts/SelectorView.js" type="text/javascript"></script>
    <script src="scripts/SortView.js" type="text/javascript"></script>
    <script src="scripts/TableView.js" type="text/javascript"></script>
 
  <script type="text/javascript">
  $ (document).ready (function() {
   var sel = new SelectorView('sel_div');
    sel.src.header = {
     id   : '编号',
     name  : '姓名',
     address: '地址'
     
    };
    sel.dst.header = {
     id : '编号',
     name: '姓名',
     address: '地址'
    };
    sel.src.dataKey = 'id';
    sel.src.title = '可选';
    
    sel.dst.dataKey = 'id';
    sel.dst.title = '已选';
    sel.render();
    $.getJSON("servlet/TableServlet?flag=query", "", function(response){
        $.each(response,function(i){
         sel.src.add({id: response[i].id, name: response[i].name, address: response[i].address});
        })
       sel.render();
      });
    });
  </script>
  </head>
 
   
  <body>
   
 <div id="sel_div"></div>

 


  </body>
</html>



最后在浏览器URL中输入:http://localhost:8080/TableWebProject/pagerList.jsp运行结果

   

一些资源

一个jQuery的Ajax Form表单插件:http://www.malsup.com/jquery/form/

一个专门生成Loading图片的站点:http://ajaxload.info/   大家觉得那些Loading比较炫的可以在这里跟帖晒一下,方便大家取用,嘎嘎



 

posted @ 2011-03-02 15:11 龍ぜ殘剑 阅读(350) | 评论 (0)编辑 收藏

AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。

传统的web应用允许用户填写表单(form),当提交表单时就向web服务器发送一个请求。服务器接收并处理传来的表单,然后返回一个新的网页。这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML代码往往是相同的。由于每次应用的交互都需要向服务器发送请求,应用的响应时间就依赖于服务器的响应时间。这导致了用户界面的响应比本地应用慢得多。

与此不同,AJAX应用可以仅向服务器发送并取回必需的数据,它使用SOAP或其它一些基于XML的web service接口,并在客户端采用JavaScript处理来自服务器的响应。因为在服务器和浏览器之间交换的数据大量减少,结果我们就能看到响应更快的应用。同时很多的处理工作可以在发出请求的客户端机器上完成,所以Web服务器的处理时间也减少了。

Ajax应用程序的优势在于:

1. 通过异步模式,提升了用户体验

2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

3. Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
 

XMLHttpRequest 对象

通过使用 XMLHttpRequest 对象,web 开发者可以做到在页面已加载后从服务器更新页面!



Ajax属性:

1. onreadystatechange 属性

onreadystatechange 属性存有处理服务器响应的函数。下面的代码定义一个空的函数,可同时对 onreadystatechange 属性进行设置:


例如:
 function getResult(username,password){
      
         createXmlHttp();                                //创建XMLHttpRequest对象
         xmlHttp.open("POST", "UserServlet?flag=add&username="+username+"&password="+password);

2. readyState 属性

readyState 属性存有服务器响应的状态信息。每当 readyState 改变时,onreadystatechange 函数就会被执行。


状态
描述
 0
请求未初始化(在调用 open() 之前)
  1 请求已提出(调用 send() 之前)
 2 请求已发送(这里通常可以从响应得到内容头部)
  3
请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应)
  4 请求已完成(可以访问服务器响应并使用它)
       
其中send()方法需要包含有三个参数,第一个是发送请求所使用的(Get()和Post()方法),第二个参数是规定服务器端脚本的Url,三个参数规定是设置对请求进行异步处理。

咱们不再这里费口舌了,来个Servlet Ajax的小例子吧:
 首先 我们来配置Web.xml。在里面配置一个servlet,跟往常一样:

<servlet>
      <servlet-name>selectcity</servlet-name>
      <servlet-class>com.bx.servlet.SelectCityServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>selectcity</servlet-name>
      <url-pattern>/selectCityServlet</url-pattern>
   </servlet-mapping>

现在看我们的.jsp 文件:

<html>
<head>
<title>select city</title>

</head>
<script type="text/javascript">

function getResult(stateVal) {
    alert(stateVal);
   var url = "selectCityServlet?state="+stateVal;
   if (window.XMLHttpRequest) {
         req = new XMLHttpRequest();
   }else if (window.ActiveXObject) {
         req = new ActiveXObject("Microsoft.XMLHTTP");
   }
   if(req){
    req.open("GET",url, true);
    req.onreadystatechange = complete;
    req.send(null);
      }
}

function complete(){
   if (req.readyState == 4) {
      if (req.status == 200) {
    var city = req.responseXML.getElementsByTagName("city");
    var str=new Array();
    for(var i=0;i<city.length;i++){
       str[i]=city[i].firstChild.data;
             }
  
         buildSelect(str,document.getElementById("city"));
     }
   }
}
function buildSelect(str,sel) {
      
   for(var i=0;i<str.length;i++) {
       sel.options[sel.options.length]=new Option(str[i],str[i]);
   }
}
</script>
<body>
<select name="state" onChange="getResult(this.value)">
   <option value="">Select</option>
    <option value="zj">浙江</option>
    <option value="zs">江苏</option>
</select>

<select id="city">
   <option value="">CITY</option>
</select>
</body>
</html>


最后我们来看看servlet文件吧:

public class SelectCityServlet extends HttpServlet {

 
  public SelectCityServlet() {
    super();
  }

  public void destroy() {
    super.destroy();
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
   
  
     try {
   Thread.sleep(1000*3);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("Hello | " + request.getParameter("state"));
  response.setContentType("text/xml");
  response.setCharacterEncoding("utf-8");
     response.setHeader("Cache-Control", "no-cache");
     String state = request.getParameter("state");
  StringBuffer sb=new StringBuffer("<state>");
     if ("zj".equals(state)){
    sb.append("<city>hangzhou</city><city>huzhou</city>");
  } else if("zs".equals(state)){
    sb.append("<city>nanjing</city><city>yangzhou</city><city>suzhou</city>");
     } else if("hb".equals(state)){
       sb.append("<city>tangshan</city><city>handan</city>");
      
     }
  sb.append("</state>");
  System.out.println(sb);
  PrintWriter out=response.getWriter();
  out.write(sb.toString());
  out.close();
  
   }
   }


这里是不是挺简单的呢,首先是通过request取得state参数,然后通过state参数生成相应的xml文件,最后在讲xml中的数据从printWriter输出。。目前为止,这个例子已经结束了,是不是挺简单的呢??

运行结果如下:
 


posted @ 2011-01-01 12:36 龍ぜ殘剑 阅读(2504) | 评论 (0)编辑 收藏
MVC
 

MVC (Model View Controler) 本来是存在于Desktop程序中的,M是指的是数据模型,V是指的是用户界面,C则是控制器。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如说一批统计数据你可以分别用柱状图,饼状图来表示。C存在的目的是确保M和V的同步,一旦M改变了,V应该同步更新。


MVC构架为:
      

  
说明:
 




模型——视图——控制器(MVC)是Xerox PARC在很在代为编程的语言Smalltalk--80发明的一种软件设计模式,至今运用仍为广泛。最近几年被推荐为Sun公司J2EE平台设计模式,并且受到越来越多的使用 ColdFusion 和 PHP 的开发者的欢迎。模型-视图-控制器模式是一个有用的工具箱,它有很多好处,但也有一些缺点。

 MVC如何工作

  MVC是一个设计模式,他是强制的使用程序的输入,处理和输出分开。使用MVC应用程序分成了三个核心部件:模型,视图,控制器。他们各自处理自己的任务。



模型

模型表示企业数据和业务规则。在MVC的三个部件中,模型拥有最多的处理任务。例如它可能用象EJBs和ColdFusion Components这样的构件对象来处理数据库。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。


视图

    视图是用户看到并与之交互的界面。如何处理应用程序界面变得越来越有挑战性。MVC一个大的好处是他能为你的应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。

 
控制器

控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后用确定用哪个视图来显示模型处理返回的数据。


MVC并不适合小型甚至中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。但是MVC设计模式是一个很好创建软件的途径,它所提倡的一些原则,像内容和显示互相分离可能比较好理解。但是如果你要隔离模型、视图和控制器的构件,你可能需要重新思考你的应用程序,尤其是应用程序的构架方面。如果你肯接受MVC,并且有能力应付它所带来的额外的工作和复杂性,MVC将会使你的软件在健壮性,代码重用和结构方面上一个新的台阶。


这里我做了个比较简单的程序其中使用了MVC思想:
在这里创建了一个实体的类,也就是M(model),即User类:

package com.bx.jstl;

public class User {
 private int id;  //声明了两给属性;
 private String name;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 

}


然后在此编写了一个类JSTLServlet 是继承了类HttpServlet类的:

package com.bx.JSServlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bx.jstl.User;

public class JSTLServlet extends HttpServlet{
 public void doGet(HttpServletRequest request , HttpServletResponse response)
  throws IOException , ServletException
 {
  List<User> list = new ArrayList<User>();
     for(int i = 0 ; i < 8 ; i++)
     {
      User u = new User();
    u.setId(i);
    u.setName("name"+i);
    list.add(u);
     }
     request.setAttribute("UserList", list);
     request.getRequestDispatcher("/c_forEach.jsp").forward(request, response);
 }
}
现在我们应该来配置WEB.xml了,这是每个Web项目都做的一步,如下所示:

<servlet>
 <servlet-name>JSTLServlet</servlet-name>
 <servlet-class>com.bx.JSServlet.JSTLServlet</servlet-class>
</servlet>

<servlet-mapping>
 <servlet-name>JSTLServlet</servlet-name>
 <url-pattern>/jstl</url-pattern>
</servlet-mapping>

下面我们建立一个c_forEach.jsp,在其body中的编写代码如下:

<table>
     <tr><th>ID</th><th>index</th><th>count</th><th>isFirst?</th><th>isLast</th></tr>
     
     <c:forEach var="user" items="${UserList}" varStatus="status">
       <tr>
    <td>
     ${user.id}
    </td>
    <td>
     ${user.name}
    </td>
    <td>
     ${status.index}
    </td>
    <td>
     ${status.count}
    </td>
    <td>
     ${status.first}
    </td>
    <td>
     ${status.last}
    </td>
        </tr>
     </c:forEach>
    </table>

现在我们开启comcat 运行此项目,在浏览器中输入:

http://localhost:8080/JSP_JSTL_Project/jstl

得到网页为:
 









posted @ 2010-12-11 17:45 龍ぜ殘剑 阅读(1364) | 评论 (2)编辑 收藏

       java对cookie的操作其实不是很难的,主要就是对cookie 的建立和cookie的读取操作吧,还有对cookie的生命周期的设置,和cookie的路径的设置。。。。
 
一:首先我们建立一个有生命周期的cookie吧,代码如下:

             int seconds=saveTime*24*60*60;//这里是一天为单位设置其周期
             Cookie cookie=new Cookie("cookiename","cookievalue");
             cookie.setMaxAge(sendons);
            //设置路径,这个路径即为该工程下都可以访问该cookie如果不设置路径,那么设置该路径cookie路径及其路径可以访问
              cookie.setPath("/");
             response.addCookie(cookie);

二:建立一个没有生命周期的cookie,即随着浏览器的关闭就消失的cookie,代码如下: 

           HttpServletRequeset  request;
           HttpServletResponse response;
           Cookie  cookie=new Cookie("cookiename","cookievalue");// 相当于一个Map
           response.addCookie(cookie);

:下面我介绍如何读取cookie吧,代码如下:

             Cookie[] cookies=request.getCookies();
              String[]    cooks=null;
              String username=null; 
               String password=null;
              if(cookie!=null){
                 
                  for(Cookie coo:cookies){
                      String aa=coo.getValue();
                       cookie=aa.split("==");
                     if(cooks.length==2){
                        
                           username=cooks[0];//get  the cookie name
                          password=cooks[1];//get the cookie  value

                       }
                    }
                }
posted @ 2010-12-11 16:05 龍ぜ殘剑 阅读(1724) | 评论 (2)编辑 收藏

    基于数据库的Java Web

现今所有的 Web都是基于数据库的,可见数据库在Web中的开发时如此的重要。然而基本上所有的网站都是要求客户登陆的时候都必须事先注册账号,这样才能进入网页,访问其中的页面,资源。。开发基于数据库的Web程序时,涉及到多个用户同时请求与数据库建立"连接"的问题,但多用户并发处理目前还是一个难点。该文在对传统数据连接模式的分析基础上,采用了一种基于对象的数据连接池的设计方案。通过连接对象放置预先建立的若干"连接",根据一定的策略管理这些"连接",防止"连接"过多内存开销过大,及连接排队过长问题。并用JAVA实现了该方案,在实际应用中提供了一个高效的连接管理策略,提高了Web数据库应用系统的性能。

  一:在此我通过一个实际的例子谈谈我最近最Web得心得,首先我们建立一个javaWeb项目在Myeclipse下。首先建立好数据库连接,即建立一个Vo对象User类,如下:
package vo;
/*
 
用户名称:<input type="text" name="username"><br>
用户密码:<input type="password" name="password"><br>
用户爱好:<input type="checkbox" name="hobby" value="1">游泳
  <input type="checkbox" name="hobby" value="2">足球<br>
用户性别:<input type="radio" name="gender" value="male">男
  <input type="radio" name="gender" value="female">女
  <input type="radio" name="gender" value="secret">保密<br>
用户职位:<select name="position">
  <option value="CEO">CEO</option>
  <option value="CFO">CFO</option>
  <option value="CTO">CTO</option>
  </select><br>
用户简历:<textarea rows="5" cols="20" name="resume"></textarea>
       <input type="submit" value="注册">
       */
public class User {
 
 private int id;
 private String userName;
 private String passWord;
 private String hobby;
 private String gender;
 private String position;
 private String resume;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 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 String getHobby() {
  return hobby;
 }
 public void setHobby(String hobby) {
  this.hobby = hobby;
 }
 public String getGender() {
  return gender;
 }
 public void setGender(String gender) {
  this.gender = gender;
 }
 public String getPosition() {
  return position;
 }
 public void setPosition(String position) {
  this.position = position;
 }
 public String getResume() {
  return resume;
 }
 public void setResume(String resume) {
  this.resume = resume;
 }
 

}


二:这样我们建立好了实体对象之后,现在我们来建立UserDAO接口和DAOFactory两个类如下:

package dao;

import vo.User;

public interface UserDAO {
 
 //建立一个接口
 
 void save(User user);

}


 

package factory;

import impl.UserDaoImpl;
import dao.UserDAO;

public class DAOFactory {
 public static UserDAO getUserDAOInstance(){
  
  
  return new UserDaoImpl();
 }

}


三:现在我们来建立ConnectionUtil类,这里我才用我们最常用的一种方法来连接数据库Database即:

package db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class ConnectionUtil {

  public Connection openConnection() {
  
  String driver = "";
  String url = "";
  String user = "";
  String password = "";
  Properties prop = new Properties();   //实例化一个配置文件的对象
  Connection conn = null;
  try {
   // 加载属性文件
   prop.load(this.getClass().getClassLoader().getResourceAsStream(
     "DBConfig.properties"));
   driver = prop.getProperty("driver");
   url = prop.getProperty("url");
   user = prop.getProperty("user");
   password = prop.getProperty("password");
   // Class.forName加载驱动
   Class.forName(driver);
   // DriverManager获得连接
   conn = DriverManager.getConnection(url,
     user, password);
   return conn;
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
}

四:是实现Java程序与数据库的链接层建立一个UserDaoImpl类:


package impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

 

import vo.User;
import dao.UserDAO;
import db.ConnectionUtil;

public class UserDaoImpl implements UserDAO{
 //实现接口UerDAO

 public void save(User user) {
  
  
  //实现接口类中的方法
  ConnectionUtil cu=new ConnectionUtil();//初始化连接的数据库
  Connection conn=cu.openConnection();
  String sql = "insert into User(username,password,hobby,gender,position,resume) values(?,?,?,?,?,?)";
  try {
   PreparedStatement pstmt = conn.prepareStatement(sql);
   
   pstmt.setString(1, user.getUserName());
   pstmt.setString(2, user.getPassWord());
   pstmt.setString(3, user.getHobby());
   pstmt.setString(4, user.getGender());
   pstmt.setString(5, user.getPosition());
   pstmt.setString(6, user.getResume());
   
   pstmt.executeUpdate();
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   try {
    conn.close();//关闭连接数据库
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
 }
 }



五:是通过网站往数据库中加载数据,如下:


 

package com.bx.Servletform;

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;

import dao.UserDAO;

import factory.DAOFactory;

import vo.User;

public class RegisterServlet extends HttpServlet {
 
  
 public void doPost(HttpServletRequest request,HttpServletResponse response)
 throws ServletException,IOException{
  String username=request.getParameter("username");
  String password=request.getParameter("password");
  String[] hobby=request.getParameterValues("hobby");
  String gender=request.getParameter("gender");
  String resume=request.getParameter("resume");
  String position=request.getParameter("position");
  User user=new User();
  user.setUserName(username);
  user.setGender(gender);
  user.setPassWord(password);
  user.setPosition(position);
  user.setResume(resume);
  String hobbyStr="";
  if(hobby!=null&&hobby.length>0){
   for(int i=0;i<hobby.length;i++){
    hobbyStr=hobby[i]+":";
   }
  }
  user.setHobby(hobbyStr);
  UserDAO udao=DAOFactory.getUserDAOInstance();
  udao.save(user);
  PrintWriter out=response.getWriter();
  out.println("Hello World Servlet james");
  System.out.println("username |"+username);
  System.out.println("password |"+password);
  System.out.println("gender |"+gender);
  System.out.println("resume |"+resume);
  System.out.println("position |"+position);
  if(hobby!=null&& hobby.length>0){
   for(int i=0;i<hobby.length;i++){
    System.out.println(hobby[i]);
   }
  }
  //实现页面的跳转
  if(username!=null && username.equals("james")){
   
   request.getRequestDispatcher("/success.html").forward(request, response);
  
     }else{
  request.getRequestDispatcher("/failure.jsp").forward(request, response);
  
 }
 }


现在我们来配置一下register,jsp吧,如下:

<form action="/Servlet_Form_Project/form" method="post">
<!--form 中有两个最为重要的属性-->
    用户名称:<input type="text" name="username"><br>
    用户密码:<input type="password" name="password"><br>
    用户爱好:<input type="checkbox" name="hobby" value="1">游泳
      <input type="checkbox" name="hobby" value="2">足球<br>
    用户性别:<input type="radio" name="gender" value="male">男
      <input type="radio" name="gender" value="female">女
      <input type="radio" name="gender" value="secret">保密<br>
    用户职位:<select name="position">
      <option value="CEO">CEO</option>
      <option value="CFO">CFO</option>
      <option value="CTO">CTO</option>
      </select><br>
    用户简历:<textarea rows="5" cols="20" name="resume"></textarea><br/>
           <input type="submit" value="注册">
   </form>


试图效果如下:
 


现在我们来配置一下WEB.xml如下所示:
 <servlet>
         <servlet-name>RegisterServlet</servlet-name>
        <servlet-class>com.bx.Servletform.RegisterServlet</servlet-class>
 <!-- this is servlet -->
 </servlet>
 <servlet-mapping>
        <servlet-name>RegisterServlet</servlet-name>
        <url-pattern>/form</url-pattern>
    </servlet-mapping>


在此我们已经完成了Java Web与数据库的连接:至此我们可以开始comcat,在浏览器中输入连接的地址即:http://localhost:8080/Servlet_Form_Project/register.jsp
得到页面为:
   
这时候我们可以查看数据库中是否在如了我们输入的数据即:

 

posted @ 2010-12-09 20:55 龍ぜ殘剑 阅读(4392) | 评论 (2)编辑 收藏
 
一:软件下载
   1.Java

  这里我使用的是jdk1.6.0...
  
  2.tomcat

   我使用的是tomcat的版本是6.0.29的,安装版或者是解压版的都可以使用,只是有一点不同而已。
  
  3.数据库

   推荐使用 MySQL,    因为MySQL使用更加的解洁,明了。。

二:软件安装

 1.双击安装jdk。
    装完后在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量:
  
  (假设你的JDK安装在c:/jdk)
  JDK_HOME=C:\jdk
  classpath=.;%JDK_HOME%\lib\dt.jar;%JDK_HOME%\lib\tools.jar
  在PATH(原来就已存在)中添加:%JDK_HOME%\bin
  这样jdk环境配置成功。
  
  2.双击安装你的Tomcat。(建议安装在一个盘的根目录下入D:/tomcat)
  
  注:apache-tomcat-6.0.29这是免安装版的。。嘿嘿
  这样已经完整安装完Tomcat了。
  建议:在PATH中再添加:%JDK_HOME%\bin;%TOMCAT_HOME%\bin
  这样做的目的是在虚拟dos中可以使用tomcat的工具
  最后顺便把第一步下载回来的三个jar文件放到tomcat目录下的common/lib目录中
  
  3.测试:
  
  打开开始菜单中的tomcat(小猫图案)的monitor工具,点击start server,显示绿色三角形即为启动,打开浏览器在地址栏输入:http://localhost:8080/可以看到小猫图案说明已经配置成功。
  
  4.安装数据库(sqlserver)
  
  windows xp下必须安装个人版或开发版(个人推荐个人版)。
  
  一直next就可以(微软的东西就是方便),这里注意到域帐户那里选择本机帐户,到验证那里选择混合验证(这点很重要,若选择系统认证以后在程序中就连接不上数据库),为你的sa用户输入一个密码(如果练习用就不用考虑安全性啦,选择“空密码”就可以)

一切都准备好,我们具体的做一个小程序吧:
           1.建立一个继承于HttpServlet的类TestServlet,在里面写HttpServlet中的方法,一般常用的方法有doGet(),doPost(),doPut(),doDelete()其中最常用的有doGet(),doPost()两个方法。。
      代码如下:
            

package com.dr.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet{
 public void init(){
  System.out.println("hello");
 }
 
 public void doGet(HttpServletRequest request,HttpServletResponse response)
 {
  System.out.println("how are you");
 }
 public void doPost(HttpServletRequest request,HttpServletResponse response)
 throws ServletException,IOException{
  String username=request.getParameter("username");
  String pws=request.getParameter("password");
  System.out.println(username);
  System.out.println(pws);
  //实现页面的跳转
  if(username!=null && username.equals("james")){
   
    request.getRequestDispatcher("/successfull.html").forward(request, response);
   
  }else{
   request.getRequestDispatcher("/failure.html").forward(request, response);
   
  }
  
  
  
  System.out.println("doPost method");
 }
}


  2.我们应该配置web.xml文件:
   代码如下:

 <servlet>
         <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.dr.servlet.TestServlet</servlet-class>
 <!-- this is servlet -->
 </servlet>
 <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping> 


   3.下面我们配置demo.html 

      body中的代码如下:


<form name="f1" id="f1" action="/Servlet_Basic/test" method="post">
<!--其中的method="post"与"get"的区别别需要清楚,这是非常重要的-->
<table >
    
     <tr><td>账号</td> <td><input type="text" name="username" id="username"/></td></tr>
     <tr><td>密码</td> <td><input type="password" name="password" id="password"/></td></tr>
      <tr> <td colspan="3" align="center"><input type="submit" value="欢迎光临" /></td></tr>
 
 
  </table>
  
    </form>

即为:
  
  这时候你可以在启动tomcat,然后在internet中输入http://localhost:8080/Servlet_Basic/demo.html,就启动了刚才得网页,如下:
 


posted @ 2010-12-08 12:43 龍ぜ殘剑 阅读(1148) | 评论 (0)编辑 收藏
 浅谈用JDBC连接MySQL
         在学习数据库开发的实例,这里浅谈一下用JDBC连接数据库MySQL(当然也可以连接 SQL Server或者Oracle了,只是我更喜欢开源软件,同时也简单些。。。)

首先正确安装好MySQL,建立好数据库,下面我们来建立一个数据库吧。

           JDBC连接MySQL
                加载节注册JDBC驱动程序,
                         Class.forName("com.mysql.jdbc.Driver");
                        Class.forName("com.mysql.jdbc.Driver").newInstance();
            JDBC URL定义驱动程序与数据库之间的链接
                        标准语法:

                             <protocol(主要通信协议)>:<subprotocol(次要通讯协议,驱动程序名称)>:<data source identifier(数据源)>

                        MySQL JDBC URL的格式:

                              jdbc:mysql://[hostname][:port]/[dbname][?param1=value1][&param2=value2]….

                        例如:

                               jdbc:mysql://localhost:3306/jdbc_db","root","1234"
                        

常见参数:

user                       用户名

password                  密码

autoReconnect                  联机失败,是否重新联机(true/false

maxReconnect              尝试重新联机次数

initialTimeout               尝试重新联机间隔

maxRows                   传回最大行数

useUnicode                 是否使用Unicode字体编码(true/false

characterEncoding          何种编码(GB2312/UTF-8/…

relaxAutocommit            是否自动提交(true/false

capitalizeTypeNames        数据定义的名称以大写表示
 

                      JDBC访问数据库的步骤:

                           1.加载数据库驱动

                           2.获得数据库连接

                           3.创建SQL语句

                           4.执行查询

                           5.遍历结果集

                           6.关闭数据库连接
  数据库的链接一般有三种方法,这里简单说一种,有小例子如下:
           

    ckage com.bx.jdbc;

    port java.sql.Connection;
    port java.sql.DriverManager;
    port java.util.Properties;

public class ConnectionUtil {

 public Connection openConnection() {
  
  String driver = "";
  String url = "";
  String user = "";
  String password = "";
  Properties prop = new Properties();
  Connection conn = null;
  try {
   // 加载属性文件
   prop.load(this.getClass().getClassLoader().getResourceAsStream(
     "DBConfig.properties"));
   driver = prop.getProperty("driver");
   url = prop.getProperty("url");
   user = prop.getProperty("user");
   password = prop.getProperty("password");

   // Class.forName加载驱动
   Class.forName(driver);

   // DriverManager获得连接
   conn = DriverManager.getConnection(url,user, password);
   return conn;
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
}
执行的主函数如下:

package com.bx.jdbc;

public class Main {
 /**
  * @param args
  */
 public static void main(String[] args) {
  ConnectionUtil cu = new ConnectionUtil();

  // 第三种方法
  System.out.println("这是最常用的一种方法:" + cu.openConnection());
 }
}

执行结果:
 

谢谢大家分享,但愿能对您带来一点帮助,希望能帮提出宝贵的意见。。。
posted @ 2010-12-08 09:03 龍ぜ殘剑 阅读(2470) | 评论 (2)编辑 收藏
posted @ 2010-12-07 16:49 龍ぜ殘剑 阅读(120) | 评论 (0)编辑 收藏
杀毒软件:
杀毒软件是每一台电脑不可少的应用软件之一,现在我来研究 一下杀毒软件的整个工作流程吧。。。首先要明确杀毒软件的目的是什么,怎么样才能实现这一目的。。。
杀毒软件是客户在通过扫描自己的电脑里的每一个文件,然后与杀毒软件服务器病毒库里的病毒相比较,如果你电脑里有和服务器中文件相同的,杀毒软件就视为是病毒,然后有用户选择是否要把扫描出来的文件删除。。。。下面是我用Java语言来实现这个功能的。。。希望对大家有所感悟。现在说说我的具体实现的步骤吧。



服务器代码:

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import com.dr.bean.Virus;

 


public class Server {
 


 public static List<Virus> virusList = new ArrayList<Virus>();
 public static void main(String[] args) throws IOException {
  ServerSocket server = null;
  //输出肯定使用打印流
  PrintStream out = null;
  //服务器肯定也要接收数据
  BufferedReader buf = null;
  //实例化一个服务器的监听端
  server = new ServerSocket(8888);
  //可以用一种死循环的方式接收内容
  System.out.println("---------服务器已经启动----------");
  Socket client = null;
  //初始化暗杀名单
  //List<Virus> virusList = getVirusList();
  while(true){
   //不断接收内容
   client = server.accept();
   //准备好向客户端输入内容
   out = new PrintStream(client.getOutputStream());
   //而且客户端要有输入给服务器端
   buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
   
   
   //接收客户端发送过来的内容
   String str = buf.readLine();
   System.out.println("server receive data is:"+str);
   String virus = "";
   if("getVirusList".equals(str)){//组成暗杀协议,返回客户端
    for(Virus v :virusList){
     virus += v.getName()+":";
    }
    out.println(virus);
   }
   
   //进行收尾工作
   out.flush();
   out.close();
   buf.close();
   client.close();
  }
  
  
 }
 
 public static List<Virus> getVirusList(){
  
  Virus virus = null;
  
  virus = new Virus();
  virus.setName("QQ.exe");
  virusList.add(virus);
  
  virus = new Virus();
  virus.setName("Niu.exe");
  virusList.add(virus);
  
  virus = new Virus();
  virus.setName("Baidu.exe");
  virusList.add(virus);
  
  virus = new Virus();
  virus.setName("Jinshan.exe");
  virusList.add(virus);
  
  return virusList;
 }

 

}

执行结果:
 
客户端代码

package com.dr.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import com.dr.bean.Virus;


public class Client {

 private String str;
 private List<Virus> virusList = null;
    public Client(String str){
     this.str = str;
     virusList = new ArrayList<Virus>();
    }
 
 public List<Virus> send() throws UnknownHostException, IOException{
  Socket client = null;
  //接收服务器信息的输入流
  BufferedReader buf = null;
  //向服务器发送信息的输出流
  PrintStream out = null;
  //实例化一个套接字
  client = new Socket("localhost",8888);
  //从服务器接收信息
  buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
  //向服务器打印信息
  out = new PrintStream(client.getOutputStream());
  
  
  //打印出去
  out.println(this.str);
  //接收进来QQ.exe:baidu.exe:niu.exe
  String msg = buf.readLine();
  System.out.println(msg);
  String[] msgArray = msg.split(":");
  for(int i=0;i<msgArray.length;i++){
   Virus v = new Virus();
   v.setName(msgArray[i]);
   virusList.add(v);
   System.out.println(msgArray[i]);
  }
  

  buf.close();
  out.flush();
  out.close();
  client.close();
  
  return virusList;
 }
}

 

文件扫描过程代码类:::

package com.dr.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import com.dr.bean.Virus;


public class Client {

 private String str;
 private List<Virus> virusList = null;
    public Client(String str){
     this.str = str;
     virusList = new ArrayList<Virus>();
    }
 
 public List<Virus> send() throws UnknownHostException, IOException{
  Socket client = null;
  //接收服务器信息的输入流
  BufferedReader buf = null;
  //向服务器发送信息的输出流
  PrintStream out = null;
  //实例化一个套接字
  client = new Socket("localhost",8888);
  //从服务器接收信息
  buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
  //向服务器打印信息
  out = new PrintStream(client.getOutputStream());
  
  
  //打印出去
  out.println(this.str);
  //接收进来QQ.exe:baidu.exe:niu.exe
  String msg = buf.readLine();
  System.out.println(msg);
  String[] msgArray = msg.split(":");
  for(int i=0;i<msgArray.length;i++){
   Virus v = new Virus();
   v.setName(msgArray[i]);
   virusList.add(v);
   System.out.println(msgArray[i]);
  }
  

  buf.close();
  out.flush();
  out.close();
  client.close();
  
  return virusList;
 }
}





KillVirusUI代码:


package com.dr.ui;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.dr.file.FileList;

public class KillVirusUI {

 public static String filePath = "";
 public static List<String> virusFilePath = new ArrayList<String>();
 public static void main(String args[]) {
  Display display = new Display();
  final Shell shell = new Shell(display, SWT.SHELL_TRIM);
  shell.setBounds(2, 2, 1200, 600);
  //shell.setMaximized(true);// 全屏显示
  shell.setText("杀毒软件简单版");
  /**
   * 设置执行按钮
   */
  final Button btnOk = new Button(shell, SWT.PUSH);
  btnOk.setBounds(20, 25, 70, 25);
  btnOk.setText("扫描杀毒");
  final Button btnOk1 = new Button(shell, SWT.PUSH);
  btnOk1.setBounds(120, 25, 70, 25);
  btnOk1.setText("删除病毒");

   Color color = new Color(Display.getCurrent(), 100, 180, 10);// 声明颜色对象
   Color color1 = new Color(Display.getCurrent(), 100, 220, 240);// 声明颜色对象
  final Text text = new Text(shell, SWT.MULTI | SWT.BORDER);
  text.setBounds(10, 270, 1200, 400);
  text.setBackground(color1);
  final Text text1 = new Text(shell, SWT.MULTI | SWT.BORDER);
  text1.setBounds(10, 150, 1200, 50);
  text1.setBackground(color1);
  
  final ProgressBar progressBar = new ProgressBar(shell, SWT.HORIZONTAL);
  GridData data = new GridData();
  data.horizontalSpan = 2;
  data.grabExcessHorizontalSpace = true;
  progressBar.setLayoutData(data);
  progressBar.setMaximum(100);// 设置最大值
  progressBar.setMinimum(0);// 设置最小值
  /**
   * 注册点击事件,循环显示数据
   */
  
  Label labe=new Label(shell,SWT.NULL);
     labe.setBounds(800,25, 120,75); // 设置按钮位置
     labe.setFont(new Font(display,"宋体",20,SWT.BOLD));
   
   
     labe.setBackground( color);
  labe.setText("    "+"360"+"\n"+"网络保镖");
  ;
  btnOk.addSelectionListener(new SelectionAdapter() {//Button监听事件
   public void widgetSelected(SelectionEvent e) {
    FileList f = new FileList();
    DirectoryDialog dlg = new DirectoryDialog(shell);
    dlg.setText("目录"); // 设置窗口标题
    dlg.setMessage("请选择一个目录:"); // 设置提示文字
    dlg.setFilterPath("/root"); // 设置初始目录
    String dir = dlg.open(); // 打开对话框并返回一个包含所选目录路径的字符串
    
    //File f=new File(dlg.open());
       f.setStr(dir);
    
    if (f != null)
     System.out.println(f); // 比如选择“我的文档”,则会打印“D:\My Documents”
    
    
    Thread t = new Thread(f);
    t.setDaemon(true);
    t.start();
    t.yield();
    
    for(int i=0;i<100;i++){
     text.append(filePath+"\n"); 
     progressBar.setBounds(10, 80, 1200, 20);
     progressBar.setSelection(progressBar.getSelection()+1);//显示一条数据,滚动条进度加1
     try {
      Thread.sleep(1000);
     } catch (InterruptedException e1) {
      e1.printStackTrace();
     }
    }
    
    if(virusFilePath.size()!=0){
     text.setText("");
     for(String str : virusFilePath){
      text1.append("很悲剧:你的电脑里发现病毒:"+str+"\n");
     }
    }
    else{
     text1.setText("恭喜你,没有发现病毒!");
    }
    t.interrupt();
    
   }
  
  });
  
  
  btnOk1.addSelectionListener(new SelectionAdapter() {//Button监听事件
   public void widgetSelected(SelectionEvent e) {
    FileList q = new FileList();
    Thread t = new Thread(q);
    t.setDaemon(true);
    t.start();
    for(int i=0;i<100;i++){
     text.append(filePath+"\n");
     progressBar.setBounds(10, 105, 1200, 20);
     progressBar.setSelection(progressBar.getSelection()+1);//显示一条数据,滚动条进度加1
     try {
      Thread.sleep(100);
     } catch (InterruptedException e1) {
      e1.printStackTrace();
     }
    }
    
    if(virusFilePath.size()!=0){
     text.setText("");
     for(String str : virusFilePath){
      //text1.append("发现病毒:"+str+"\n");
      
         File f1=new File("f.filePath");
      f1.delete();
      text1.append("恭喜你已经成功清理了电脑里的病毒:"+str+"\n");
     }
    }
    else{
     text1.setText("祝贺你不用为电脑安危考虑了!");
    }
   }
   });
  
  
  shell.open();
  while (!shell.isDisposed()) {
   if (!display.readAndDispatch())
    display.sleep();
  }
  display.dispose();
 }
}

执行结果:

 
首先要启动服务器,杀毒软件才能够正常的工作。。。。。。。


病毒类:

package com.dr.bean;


public class Virus{

 private String name;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}


posted @ 2010-11-23 13:43 龍ぜ殘剑 阅读(2101) | 评论 (2)编辑 收藏
  图形用户界面:
在Java 中,顶层窗口成为框架。对应于SWT库中,其框架主要是Frame,而在Swing库中,则对应的类是JFrame,JFrame类是Frame的子类,但是他们大多数情况下是等价的,只是在表示形式下多了个"J"而已。。。。Component类是所有GUI对象的祖先,Window类是Frame类的父类,JFrame类直接从Frame继承而来,下面是他们的关系图。
  
 


import javax.swing.*;
import java.awt.*;
//////////////////////////////////////////////////
public class HelloWorld
{
 public static void main(String[] args)
 { 
  TextFrame frame = new TextFrame("MyJava");          //新建图形建面MyJava
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setVisible(true);                      //设置为可视化的。。。
 }
}
/////////////////////////////////////////////////
class TextFrame extends JFrame
{
 public static final int WIDTH = 300;
 public static final int HEIGHT = 200; 
 
 public TextFrame()
 {
  setTitle("HelloWorld");
  setSize(WIDTH, HEIGHT);
  
  //将panel加入到frame
  TextPanel panel = new TextPanel();
  Container contentPane = getContentPane();
  contentPane.add(panel); //要在内容窗格中加入图形元素(容器)
 }
 
 
}
//////////////////////////////////////////////////////////////////
class TextPanel extends JPanel         //组件容器

 public int x = 100;
 public int y = 100;
 
 public void paintComponent(Graphics g)
 { 
  super.paintComponent(g);
  
  //显示文本
  g.drawString(" Hello, World!", x, y);
 }
 

}
事件处理:
如果用户在用户界面执行了一个动作,这将导致一个事件发生。事件的描述发生了什么的对象,在Java中,定义了各种不同的事件类,来描述各种类型的用户操作。事件是由事件源产生的,事件的产生者成为事件源。。。
事件处理逻辑(事件。事件源。和处理方法之间的关系)可以用一下四个步骤表示:
 

 

posted @ 2010-11-11 19:53 龍ぜ殘剑 阅读(134) | 评论 (0)编辑 收藏

 

面向对象=对象+继承+类+通信。面向对象是以对象(Object)的概念为核心,专注于对象的操纵。。面向对象最为突出的特点是继承...封装....多态。
对象:是一个抽象的是体,eg:苹果是一个类,有不同口味的,不同种类的苹果。然而说这里有个苹果,则是一个实例对象。书:是一个类,说这里有一本《计算机网络》,则是一个实例对象。。
继承:所表达的是对象之间的相交关系,是使一个对象可以继承其他对象类的特征和能力。。。
一组客观对象的抽象,具有相同的数据结构和相同的操作对象集合。。

 
Eg:

class Demo {
 {
  // 构造块
  System.out.println("Demo类中的构造块~~~");
 }

 Demo() {
  System.out.println("Demo类中的构造方法~~~");
 }

 // 静态块
 static {
  System.out.println("Demo类中的静态块~~~");
 }
}

public class Demo24 {
 // 在主类中写的静态块要优先于main方法执行
 static {
  System.out.println("##################");
 }

 public static void main(String args[]) {
  new Demo();
  new Demo();
  new Demo();
 new Demo();
  new Demo();
 }
}
谈谈Java下的集合吧:

向量(Vecter):用capacity()方法控制其容量,空间是成倍的增长,可加入大量元素的组件。。
线性表(List):有限元素组成的有序序列,表长(length),表头(head),表尾(tail)....
堆栈(stack):实际上就是只能在一端进行插入和删除 的线性表。。只能插入和删除的一端是栈顶(top),另一端是栈底(bottom)...Last-in.First-out。。。。
 
队列(Queue):也是只能在一端进行插入和删除操作,对头(front)只能进行删除操作,队尾(back)只能插入操作。。First In First Out...........


posted @ 2010-11-11 11:06 龍ぜ殘剑 阅读(129) | 评论 (0)编辑 收藏
首先 我们说说 网络 吧,网络互联设备协议(OIS)参考模型分成了七层,即应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。。。但是在Java中只注重与应用层..网络层..与传输层,在其他方面不能够更好的服务与程序的操作和控制。然而在java中式有服务器(Server)和客服(Cliect)组成的,这两者之间一般情况 是成对出现的。。。对服务器而言如果客服对服务器发送请求,,则服务器是InputStream数据,二客服则是OutputStream数据。。。两者之间也是相对的。。。。
我做了个小例子如下:

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class Server03 {
 public static void main(String args[])throws IOException{
  ServerSocket ss=new ServerSocket(9999);
  while(true){
   System.out.println("----server端");
         Socket s=ss.accept();
   
         DataOutputStream dos=new DataOutputStream(s.getOutputStream());
  
         dos.writeUTF("客服端"+s.getInetAddress().getHostAddress()+""+s.getPort()+"已连接"+
           s.getInetAddress().getHostAddress()+s.getLocalPort());
   
  dos.flush();
  dos.close();
  s.close();
  }
  
 }

}

 

执行结果:
 
客服端的程序:

 

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;


public class Cliecnt02 {
 public static void main(String args[])throws IOException{
  for(int i=0;i<20000;i++){
   Socket s=new Socket("127.0.0.1",9999);
   DataInputStream dis=new DataInputStream(s.getInputStream());
   System.out.println("客服端连接的数据"+dis.readUTF());
   dis.close();
   s.close();
  }
  
 }

}

执行结果:
 

小结:一般情况下一台服务器上可以为很多的电脑提供服务。。。。只要改变端口号就可以 了

posted @ 2010-11-10 22:28 龍ぜ殘剑 阅读(876) | 评论 (0)编辑 收藏
<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜