Java制作

分分钟实现模块 增、删、改、查
生成前端代码
Jsp、Jquery、Bootstrap
预览生成的代码
Struts2 Spring Mybatis
生成数据库代码
生成可部署执行代码
Eclipse Tomcat
本项目由“程驰天下”开发,免费提供给Java爱好者使用,希望能提高您的工作效率!
AutoJCode开发QQ群:邮箱:欢迎大家提出宝贵意见Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。
Java可运行于多个平台,如Windows, Mac OS,及其他多种UNIX版本的系统。
本教程通过简单的实例将让大家更好的了解JAVA编程语言。
我的第一个JAVA程序
以下我们通过一个简单的实例来展示 Java 编程,创建文件 HelloWorld.java(文件名需与类名一致), 代码如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.println(&Hello World&);
注:String args[] 与 String[] args 都可以执行,但推荐使用 String[] args,这样可以避免歧义和误读。
运行以上实例,输出结果如下:
$ javac HelloWorld.java
$ java HelloWorld
Hello World
执行命令解析:
以上我们使用了两个命令 javac 和 java。
javac 后面跟着的是java文件的文件名,例如 HelloWorld.java。
该命令用于将 java 源文件编译为 class 字节码文件,如: javac HelloWorld.java。
运行javac命令后,如果成功编译没有错误的话,会出现一个 HelloWorld.class 的文件。
java 后面跟着的是java文件中的类名,例如 HelloWorld 就是类名,如: java HelloWorld。
注意:java命令后面不要加.class。
Gif 图演示:
开始学习JAVA编程
4个月前 (08-28)
记住登录状态
重复输入密码Java进阶之 如何自动生成代码
一、前言:为什么要有代码的自动生成?
对于这个问题 最简洁直接的回答就是:代替手动编写代码、提高工作效率。
什么样的场景和代码适合用自动生成这种方式呢?
做过服务端的朋友一定都知道代码中我们需要编写与表映射的Java实体类(Entity)、需要编写与实体对应的DAO类(XxDao.java类中有包含对应实体的增、删、改、查基本操作)。在这些实体类中通常都是一些属性方法以及属性对应的get/set方法、而实体对应的DAO类中也基本会包含有增、删、改、查这些与数据库操作相关的方法。在编写了那么多的实体类和Dao类的过程中 你是否发现了这些代码中有很多地方都相似或者差不多、只是名字不同而已呢?对、那么这个时候其实我们可以定义一个模板、通过模板我们来让代码自动生成去吧。
二、FreeMarker的简单介绍
在进入正文前,让我们首先简单、快速了解一下FreeMarker。
(做过Web开发的朋友肯定都是相当熟悉的、小吕当时 也是在做Web开发的时候第一次接触了FreeMarker)
1、概述:FreeMarker是一款模板引擎:即一种基于模板、用来生成输出文本的通用工具。更多的是被用来设计生成HTML页面。
简单说就是:FreeMarker是使用模板生成文本页面来呈现已经准备好的数据。如下图表述
FreeMarker官网:http://freemarker.org/
2、通过一个简单的例子来展示如何使用FreeMarker定义模板、绑定模型数据、生成最终显示的Html页面:
1&.新建项目 在项目根目录下新建template文件夹,用来存放我们的Template file,
如我们新建模板文件test.ftl 内容如下:
Welcome ${user}&#if user == Big Joe&, our beloved leader!
Our latest product: !
2&.项目引入freemarker.jar(下载地址:https://jarfiles.pandaidea.com/freemarker.html),
在Java类中使用FreeMarker API方法引用模板文件、创建数据模型、合并数据模型与模板文件最终输入,
代码如下:
import java.io.F
import java.io.IOE
import java.io.OutputStreamW
import java.io.W
import java.util.HashM
import java.util.M
import freemarker.template.C
import freemarker.template.DefaultObjectW
import freemarker.template.T
import freemarker.template.TemplateE
public class HtmlGeneratorClient {
public static void main(String[] args) {
Configuration cfg = new Configuration();
// 指定模板文件从何处加载的数据源,这里设置成一个文件目录
cfg.setDirectoryForTemplateLoading(new File(./template));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 获取或创建模板
Template template = cfg.getTemplate(test.ftl);
// 创建数据模型
Map root = new HashMap();
root.put(user, Big Joe);
Map latest = new HashMap();
root.put(latestProduct, latest);
latest.put(url, http://blog.csdn.net/janice0529/article/details/products/greenmouse.html);
latest.put(name, green mouse);
// 将模板和数据模型合并 输出到Console
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
3&.最终生成的HTML的页面代码如下:
Welcome Big Joe, our beloved leader!
Our latest product: !
三、如何使用FreeMerker完成Java类代码的自动生成
上面示例 我们的ftl模板文件定义的是HTML页面模板,那么我们将ftl模板定义为Java代码呢 通过数据模板的绑定不就可以生成Java类啦,
下面小吕将利用模板来自动创建实体对象的java类(编写实体类的模板文件相对逻辑简单,但简单归简单,最重要的还是我们要掌握它的思想)
1、属性类型的枚举类 PropertyType.java
* 属性类型枚举类
public enum PropertyType {
Byte, Short, Int, Long, Boolean, Float, Double, String, ByteArray, Date
2、实体对应的字段属性类 Property.java
* 实体对应的属性类
public class Property {
// 属性数据类型
private String javaT
// 属性名称
private String propertyN
private PropertyType propertyT
public String getJavaType() {
return javaT
public void setJavaType(String javaType) {
this.javaType = javaT
public String getPropertyName() {
return propertyN
public void setPropertyName(String propertyName) {
this.propertyName = propertyN
public PropertyType getPropertyType() {
return propertyT
public void setPropertyType(PropertyType propertyType) {
this.propertyType = propertyT
3、实体模型类 Entity.java
import java.util.L
public class Entity {
// 实体所在的包名
private String javaP
// 实体类名
private String classN
// 属性集合
// 是否有构造函数
public String getJavaPackage() {
return javaP
public void setJavaPackage(String javaPackage) {
this.javaPackage = javaP
public String getClassName() {
return classN
public void setClassName(String className) {
this.className = classN
public String getSuperclass() {
public void setSuperclass(String superclass) {
this.superclass =
public List getProperties() {
public void setProperties(List properties) {
this.properties =
public boolean isConstructors() {
public void setConstructors(boolean constructors) {
this.constructors =
4、在项目根目录下新建template文件夹,用来存放我们的Template file, 新建实体模板entity.ftl 内容如下:
package ${entity.javaPackage};
* This code is generated by FreeMarker
* @author lvzb.
public class ${entity.className}&#if entity.superclass?has_content& extends ${entity.superclass}
/********** attribute ***********/
&#list entity.properties as property&
private ${property.javaType} ${property.propertyName};
/********** constructors ***********/
&#if entity.constructors&
public ${entity.className}() {
public ${entity.className}(&#list entity.properties as property&${property.javaType} ${property.propertyName}&#if property_has_next&, ) {
&#list entity.properties as property&
this.${property.propertyName} = ${property.propertyName};
/********** get/set ***********/
&#list entity.properties as property&
public ${property.javaType} get${property.propertyName?cap_first}() {
return ${property.propertyName};
public void set${property.propertyName?cap_first}(${property.javaType} ${property.propertyName}) {
this.${property.propertyName} = ${property.propertyName};
5、自动生成实体类 客户端代码 EntityGeneratorClient.java
import java.io.F
import java.io.FileW
import java.io.IOE
import java.io.OutputStreamW
import java.io.W
import java.util.ArrayL
import java.util.HashM
import java.util.L
import java.util.M
import freemarker.template.C
import freemarker.template.DefaultObjectW
import freemarker.template.T
import freemarker.template.TemplateE
* 自动生成实体类客户端
* @author lvzb.
public class EntityGeneratorClient {
private static File javaFile =
public static void main(String[] args) {
Configuration cfg = new Configuration();
// 步骤一:指定 模板文件从何处加载的数据源,这里设置一个文件目录
cfg.setDirectoryForTemplateLoading(new File(./template));
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 步骤二:获取 模板文件
Template template = cfg.getTemplate(entity.ftl);
// 步骤三:创建 数据模型
Map root = createDataModel();
// 步骤四:合并 模板 和 数据模型
// 创建.java类文件
if(javaFile != null){
Writer javaWriter = new FileWriter(javaFile);
template.process(root, javaWriter);
javaWriter.flush();
System.out.println(文件生成路径: + javaFile.getCanonicalPath());
javaWriter.close();
// 输出到Console控制台
Writer out = new OutputStreamWriter(System.out);
template.process(root, out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
* 创建数据模型
private static Map createDataModel() {
Map root = new HashMap();
Entity user = new Entity();
user.setJavaPackage(com.study.entity); // 创建包名
user.setClassName(User);
// 创建类名
user.setConstructors(true); // 是否创建构造函数
// user.setSuperclass(person);
List propertyList = new ArrayList();
// 创建实体属性一
Property attribute1 = new Property();
attribute1.setJavaType(String);
attribute1.setPropertyName(name);
attribute1.setPropertyType(PropertyType.String);
// 创建实体属性二
Property attribute2 = new Property();
attribute2.setJavaType(int);
attribute2.setPropertyName(age);
attribute2.setPropertyType(PropertyType.Int);
propertyList.add(attribute1);
propertyList.add(attribute2);
// 将属性集合添加到实体对象中
user.setProperties(propertyList);
// 创建.java类文件
File outDirFile = new File(./src-template);
if(!outDirFile.exists()){
outDirFile.mkdir();
javaFile = toJavaFilename(outDirFile, user.getJavaPackage(), user.getClassName());
root.put(entity, user);
* 创建.java文件所在路径 和 返回.java文件File对象
* @param outDirFile 生成文件路径
* @param javaPackage java包名
* @param javaClassName java类名
private static File toJavaFilename(File outDirFile, String javaPackage, String javaClassName) {
String packageSubPath = javaPackage.replace('.', '/');
File packagePath = new File(outDirFile, packageSubPath);
File file = new File(packagePath, javaClassName + .java);
if(!packagePath.exists()){
packagePath.mkdirs();
6、运行程序 我们将会在项目根目录下 生成文件夹 src-template以及自动生成的实体类User.java
效果图如下:
--- 运行后 ---&
&程序运行前目录结构& &程序运行后目录结构&
自动生成的实体类User.java 代码如下:
package com.study.
* This code is generated by FreeMarker
* @author lvzb.
public class User
/********** attribute ***********/
/********** constructors ***********/
public User() {
public User(String name, int age) {
this.name =
this.age =
/********** get/set ***********/
public String getName() {
public void setName(String name) {
this.name =
public int getAge() {
public void setAge(int age) {
this.age =
四、背后的思考
通过上面两个简单的示例我们了解到所谓的自动生成代码其实就是:
1、定义java类模板文件 2、定义模板数据 3、引用模板文件(.ftl)与模板数据合并生成Java类。
上面的示例中 有的朋友可能会问不就是要编写一个实体对象吗?干嘛搞那么麻烦、又建.ftl文件、又写了那么多类、定义模板数据的过程也是那么麻烦、我还不如手动去写、声明几个属性、set/get快捷键一下子就编写好啦。 真的是这样吗?
从一个辅助工具和软件架构的方面去思考,假设做成一个开发的辅助工具或是插件去完成实体类和对应DAO类的自动生成。假设需要建10个实体类和对应含有增删改查基本操作的DAO类。我在C/S客户端上填写包名、类名、属性字段等信息 然后一键生成,想想那是多么爽、多么痛快的一件事(当然 前提是你的模板类要编写的非常强大、通用),而你也许还在不停的 Ctrl+C、Ctrl+V。
关于如何编写.ftl模板文件、就需要自己去翻阅资料自我学习啦!一、游戏基本功能
1、能够向左向右行走(键盘监听)
2、能够跳跃
3、能够发射子弹
4、能够检测和障碍物之间的碰撞
5、背景图片的移动
二、游戏运行界面
三、游戏大致实现思路...
Java Swing打猎射击游戏编程代码下载
http://www.zuidaima.com/share/4912.htm
java swing游戏编程高仿金山打字教程-拯救苹果
源代码下载地址:http://www.zuidaima.com/share/5264.htm...
看书的时候看到一个不完整的Java编写的一个五子棋小游戏,为了恢复一下编程能力刚刚把这个小程序完成了。import java.io.BufferedR
import java.io.IOE...
1.共享数据的可见性问题可以不管,两个原因,一是可见性问题虽然虚拟机规范容许出现,但现实中极少出现;二是要保证不发生可见性问题,所有共享数据都要正确同步,这是一项艰巨的工作,另外还会带来 性能,伸缩性...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)51CTO旗下网站
用Java编写你自己的简单HTTP服务器
HTTP是个大协议,完整功能的HTTP服务器必须响应资源请求,将URL转换为本地系统的资源名。响应各种形式的HTTP请求(GET、POST等)。处理不存在的文件请求,返回各种形式的状态码,解析MIME类型等。但许多特定功能的HTTP服务器并不需要所有这些功能。
作者:yanghua_kobe来源:yanghua_kobe的博客| 13:56
HTTP是个大协议,完整功能的HTTP服务器必须响应资源请求,将URL转换为本地系统的资源名。响应各种形式的HTTP请求(GET、POST等)。处理不存在的文件请求,返回各种形式的状态码,解析MIME类型等。但许多特定功能的HTTP服务器并不需要所有这些功能。例如,很多网站只是想显示&建设中&的消息。很显然,Apache对于这样的网站是大材小用了。这样的网站完全可以使用只做一件事情的定制服务器。Java网络类库使得编写这样的单任务服务器轻而易举。
定制服务器不只是用于小网站。大流量的网站如Yahoo,也使用定制服务器,因为与一般用途的服务器相比,只做一件事情的服务器通常要快得多。针对某项任务来优化特殊用途的服务器很容易;其结果往往比需要响应很多种请求的一般用途服务器高效得多。例如,对于重复用于多页面或大流量页面中的图标和图片,用一个单独的服务器处理会更好(并且还可以避免在请求时携带不必要的Cookie,因而可以减少请求/响应数据,从而减少下载带宽,提升速度);这个服务器在启动时把所有图片文件读入内存,从RAM中直接提供这些文件,而不是每次请求都从磁盘上读取。此外,如果你不想在包含这些图片的页面请求之外单独记录这些图片,这个单独服务器则会避免在日志记录上浪费时间。
本篇为大家简要演示三种HTTP服务器:
(1) 简单的单文件服务器
(2) 重定向服务器
(3) 完整功能的HTTP服务器
简单的单文件服务器
该服务器的功能:无论接受到何种请求,都始终发送同一个文件。这个服务器命名为SingleFileHTTPServer,文件名、本地端口和内容编码方式从命令行读取。如果缺省端口,则假定端口号为80。如果缺省编码方式,则假定为ASCII。
import&java.io.*; &import&java.net.ServerS &import&java.net.S &&&public&class&SingleFileHTTPServer&extends&Thread&{ &&&&& &&&&&private&byte[]& &&&&&private&byte[]& &&&&&private&int&port=80; &&&&& &&&&&private&SingleFileHTTPServer(String&data,&String&encoding, &&&&&&&&&&&&&&&&&String&MIMEType,&int&port)&throws&UnsupportedEncodingException&{ &&&&&&&&&this(data.getBytes(encoding),&encoding,&MIMEType,&port); &&&&&} &&&&& &&&&&public&SingleFileHTTPServer(byte[]&data,&String&encoding,&String&MIMEType,&int&port)throws&UnsupportedEncodingException&{ &&&&&&&&&this.content= &&&&&&&&&this.port= &&&&&&&&&String&header=&HTTP/1.0&200&OK\r\n&+ &&&&&&&&&&&&&&Server:&OneFile&1.0\r\n&+ &&&&&&&&&&&&&&Content-length:&&+this.content.length+&\r\n&+ &&&&&&&&&&&&&&Content-type:&&+MIMEType+&\r\n\r\n&; &&&&&&&&&this.header=header.getBytes(&ASCII&); &&&&&} &&&&& &&&&&public&void&run()&{ &&&&&&&&&try&{ &&&&&&&&&&&&&ServerSocket&server=new&ServerSocket(this.port); &&&&&&&&&&&&&System.out.println(&Accepting&connections&on&port&&+server.getLocalPort()); &&&&&&&&&&&&&System.out.println(&Data&to&be&sent:&); &&&&&&&&&&&&&System.out.write(this.content); &&&&&&&&&&&&& &&&&&&&&&&&&&while&(true)&{ &&&&&&&&&&&&&&&&&Socket&connection=null; &&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&connection=server.accept(); &&&&&&&&&&&&&&&&&&&&&OutputStream&out=new&BufferedOutputStream(connection.getOutputStream()); &&&&&&&&&&&&&&&&&&&&&InputStream&in=new&BufferedInputStream(connection.getInputStream()); &&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&StringBuffer&request=new&StringBuffer(); &&&&&&&&&&&&&&&&&&&&&while&(true)&{ &&&&&&&&&&&&&&&&&&&&&&&&&int&c=in.read(); &&&&&&&&&&&&&&&&&&&&&&&&&if&(c=='\r'||c=='\n'||c==-1)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&break; &&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&&&&request.append((char)c); &&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(request.toString().indexOf(&HTTP/&)!=-1)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(this.header); &&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&out.write(this.content); &&&&&&&&&&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}finally{ &&&&&&&&&&&&&&&&&&&&&if&(connection!=null)&{ &&&&&&&&&&&&&&&&&&&&&&&&&connection.close(); &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&&&&& &&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&System.err.println(&Could&not&start&server.&Port&Occupied&); &&&&&&&&&} &&&&&} &&&&& &&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&try&{ &&&&&&&&&&&&&String&contentType=&text/plain&; &&&&&&&&&&&&&if&(args[0].endsWith(&.html&)||args[0].endsWith(&.htm&))&{ &&&&&&&&&&&&&&&&&contentType=&text/html&; &&&&&&&&&&&&&} &&&&&&&&&&&&& &&&&&&&&&&&&&InputStream&in=new&FileInputStream(args[0]); &&&&&&&&&&&&&ByteArrayOutputStream&out=new&ByteArrayOutputStream(); &&&&&&&&&&&&&int&b; &&&&&&&&&&&&&while&((b=in.read())!=-1)&{ &&&&&&&&&&&&&&&&&out.write(b); &&&&&&&&&&&&&} &&&&&&&&&&&&&byte[]&data=out.toByteArray(); &&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&int& &&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&port=Integer.parseInt(args[1]); &&&&&&&&&&&&&&&&&if&(port&1||port&65535)&{ &&&&&&&&&&&&&&&&&&&&&port=80; &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&}&catch&(Exception&e)&{ &&&&&&&&&&&&&&&&&port=80; &&&&&&&&&&&&&} &&&&&&&&&&&&& &&&&&&&&&&&&&String&encoding=&ASCII&; &&&&&&&&&&&&&if&(args.length&2)&{ &&&&&&&&&&&&&&&&&encoding=args[2]; &&&&&&&&&&&&&} &&&&&&&&&&&&& &&&&&&&&&&&&&Thread&t=new&SingleFileHTTPServer(data,&encoding,&contentType,&port); &&&&&&&&&&&&&t.start(); &&&&&&&&&&&&& &&&&&&&&&}&catch&(ArrayIndexOutOfBoundsException&e)&{ &&&&&&&&&&&&&&System.out.println(&Usage:java&SingleFileHTTPServer&filename&port&encoding&); &&&&&&&&&}catch&(Exception&e)&{ &&&&&&&&&&&&&System.err.println(e);&&&&&&&&&} &&&&&} &}&
SingleFileHTTPServer类本身是Thread的子类。它的run()方法处理入站连接。此服务器可能只是提供小文件,而且只支持低吞吐量的web网站。由于服务器对每个连接所需完成的所有工作就是检查客户端是否支持HTTP/1.0,并为连接生成一两个较小的字节数组,因此这可能已经足够了。另一方面,如果你发现客户端被拒绝,则可以使用多线程。许多事情取决于所提供文件的大小,每分钟所期望连接的峰值数和主机上Java的线程模型。对弈这个程序复杂写的服务器,使用多线程将会有明显的收益。
Run()方法在指定端口创建一个ServerSocket。然后它进入无限循环,不断地接受连接并处理连接。当接受一个socket时,就会由一个InputStream从客户端读取请求。它查看第一行是否包含字符串HTTP。如果包含此字符串,服务器就假定客户端理解HTTP/1.0或以后的版本,因此为该文件发送一个MIME首部;然后发送数据。如果客户端请求不包含字符串HTTP,服务器就忽略首部,直接发送数据。最后服务器关闭连接,尝试接受下一个连接。
而main()方法只是从命令行读取参数。从第一个命令行参数读取要提供的文件名。如果没有指定文件或者文件无法打开,就显示一条错误信息,程序退出。如果文件能够读取,其内容就读入byte数组data.关于文件的内容类型,将进行合理的猜测,结果存储在contentType变量中。接下来,从第二个命令行参数读取端口号。如果没有指定端口或第二个参数不是0到65535之间的整数,就使用端口80。从第三个命令行参数读取编码方式(前提是提供了)。否则,编码方式就假定为ASCII。然后使用这些值构造一个SingleFileHTTPServer对象,开始运行。这是唯一可能的接口。
下面是测试的结果:
命令行编译代码并设置参数:
首先,启用telnet服务(如果不会,自行google之),接着测试该主机的端口:
结果(可以看到请求的输出内容):
HTTP协议测试:
文档(这是之前一篇文章--小车动画的文档):
重定向服务器
实现的功能&&将用户从一个Web网站重定向到另一个站点。下例从命令行读取URL和端口号,打开此端口号的服务器可能速度会很快,因此不需要多线程。尽管日次,使用多线程可能还是会带来一些好处,尤其是对于网络带宽很低、吞吐量很小的网站。在此主要是为了演示,所以,已经将该服务器做成多线程的了。这里为了简单起见,为每个连接都启用了一个线程,而不是采用线程池。或许更便于理解,但这真的有些浪费系统资源并且显得低效。
import&java.io.BufferedInputS &import&java.io.BufferedW &import&java.io.IOE &import&java.io.InputStreamR &import&java.io.OutputStreamW &import&java.io.R &import&java.io.W &import&java.net.BindE &import&java.net.ServerS &import&java.net.S &import&java.util.D &&&public&class&Redirector&implements&Runnable&{ &&&&&&private&int& &&&&&private&String&newS &&&&& &&&&&public&Redirector(String&site,&int&port){ &&&&&&&&&this.port= &&&&&&&&&this.newSite= &&&&&} &&&&& &&&&&@Override&&&&&public&void&run()&{ &&&&&&&&&try&{ &&&&&&&&&&&&&ServerSocket&server=new&ServerSocket(port); &&&&&&&&&&&&&System.out.println(&Redirecting&connection&on&port&&&&&&&&&&&&&&&&&&&&&&+server.getLocalPort()+&&to&&+newSite); &&&&&&&&&&&&& &&&&&&&&&&&&&while&(true)&{ &&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&Socket&socket=server.accept(); &&&&&&&&&&&&&&&&&&&&&Thread&thread=new&RedirectThread(socket); &&&&&&&&&&&&&&&&&&&&&thread.start(); &&&&&&&&&&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&}&catch&(BindException&e)&{ &&&&&&&&&&&&&System.err.println(&Could&not&start&server.&Port&Occupied&); &&&&&&&&&}catch&(IOException&e)&{ &&&&&&&&&&&&&System.err.println(e); &&&&&&&&&} &&&&&&&&& &&&&&} &&&&& &&&&&class&RedirectThread&extends&Thread&{ &&&&&&&&&&private&Socket& &&&&&&&&& &&&&&&&&&RedirectThread(Socket&s)&{ &&&&&&&&&&&&&this.connection=s; &&&&&&&&&} &&&&&&&&& &&&&&&&&&public&void&run()&{ &&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&Writer&out=new&BufferedWriter( &&&&&&&&&&&&&&&&&&&&&&&&&new&OutputStreamWriter(connection.getOutputStream(),&ASCII&)); &&&&&&&&&&&&&&&&&Reader&in=new&InputStreamReader( &&&&&&&&&&&&&&&&&&&&&&&&&new&BufferedInputStream(connection.getInputStream())); &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&StringBuffer&request=new&StringBuffer(80); &&&&&&&&&&&&&&&&&while&(true)&{ &&&&&&&&&&&&&&&&&&&&&int&c=in.read(); &&&&&&&&&&&&&&&&&&&&&if&(c=='\t'||c=='\n'||c==-1)&{ &&&&&&&&&&&&&&&&&&&&&&&&&break; &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&request.append((char)c); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&String&get=request.toString(); &&&&&&&&&&&&&&&&&int&firstSpace=get.indexOf('&'); &&&&&&&&&&&&&&&&&int&secondSpace=get.indexOf('&',&firstSpace+1); &&&&&&&&&&&&&&&&&String&theFile=get.substring(firstSpace+1,&secondSpace); &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&if&(get.indexOf(&HTTP&)!=-1)&{ &&&&&&&&&&&&&&&&&&&&&out.write(&HTTP/1.0&302&FOUND\r\n&); &&&&&&&&&&&&&&&&&&&&&Date&now=new&Date(); &&&&&&&&&&&&&&&&&&&&&out.write(&Date:&&+now+&\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&Server:&Redirector&1.0\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&Location:&&+newSite+theFile+&\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&Content-Type:&text/html\r\n\r\n&); &&&&&&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&HTML&&HEAD&&TITLE&Document&moved&/TITLE&&/HEAD&\r\n&); &&&&&&&&&&&&&&&&&out.write(&&BODY&&H1&Document&moved&/H1&&/BODY&\r\n&); &&&&&&&&&&&&&&&&&out.write(&The&document&&+theFile &&&&&&&&&&&&&&&&&&&&&&&&&+&&has&moved&to&\r\n&A&HREF=\&&+newSite+theFile+&\&&&&&&&&&&&&&&&&&&&&&&&&&&&&+newSite+theFile &&&&&&&&&&&&&&&&&&&&&&&&&+&&/A&.\r\n&Please&update&your&bookmarks&); &&&&&&&&&&&&&&&&&out.write(&&/BODY&&/HTML&\r\n&); &&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&}finally{ &&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&if&(connection!=null)&{ &&&&&&&&&&&&&&&&&&&&&&&&&connection.close(); &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&}&catch&(IOException&e2)&{ &&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&} &&&&&&&&& &&&&&} &&&&& &&&&&&&&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&int&theP &&&&&&&&&String&theS &&&&&&&&& &&&&&&&&&try&{ &&&&&&&&&&&&&theSite=args[0]; &&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&if&(theSite.endsWith(&/&))&{ &&&&&&&&&&&&&&&&&theSite=theSite.substring(0,theSite.length()-1); &&&&&&&&&&&&&} &&&&&&&&&}&catch&(Exception&e)&{ &&&&&&&&&&&&&System.out.println(&Usage:&java&Redirector&http://www.newsite.com/&port&); &&&&&&&&&&&&&return; &&&&&&&&&} &&&&&&&&& &&&&&&&&&try&{ &&&&&&&&&&&&&thePort=Integer.parseInt(args[1]); &&&&&&&&&}&catch&(Exception&e)&{ &&&&&&&&&&&&&thePort=80; &&&&&&&&&} &&&&&&&&& &&&&&&&&&Thread&t=new&Thread(new&Redirector(theSite,&thePort)); &&&&&&&&&t.start(); &&&&&&} &&&&& &}&
HTTP测试:
侦听8010端口,此处重定向到百度:
main()方法提供一个非常简单的界面,读取新网站的URL(为了把链接重定向到该URL)和监听本地端口。它使用这些信息构造了一个Rredirector对象。然后它使用所生成的Runnable对象(Redirector实现了Runnable)来生成一个新线程并启动。如果没有指定端口,Rredirector则会监听80端口。
Redirectro的run()方法将服务器socket绑定与此端口,显示一个简短的状态消息,然后进入无限循环,监听连接。每次接受连接,返回的Socket对象会用来构造一个RedirectThread。然后这个RedirectThread被启动。所有与客户端进一步的交互由此新线程完成。Redirector的run()方法只是等待下一个入站连接。
RedirectThread的run()方法完成了很多工作。它先把一个Writer链接到Socket的输出流,把一个Reader链接到Socket的输入流。输入流和输出流都有缓冲。然后run()方法读取客户端发送的第一行。虽然客户端可能会发送整个Mime首部,但我们会忽略这些。第一行包含所有所需的信息。这一行内容可能会是这样:
GET /directory/filename.html HTTP/1.0
可能第一个词是POST或PUT,也可能没有HTTP版本。
返回的输出,第一行显示为:
HTTP/1.0 302 FOUND
这是一个HTTP/1.0响应吗,告知客户端要被重定向。第二行是&Date:&首部,给出服务器的当前时间。这一行是可选的。第三行是服务器的名和版本;这一行也是可选的,但蜘蛛程序可用它来统计记录最流行的web服务器。下一行是&Location:&首部,对于此服务器这是必须的。它告知客户端要重定向的位置。最后是标准的&Content-type:&首部。这里发送内容类型text/html,只是客户端将会看到的HTML。最后,发送一个空行来标识首部数据的结束。
如果浏览器不支持重定向,那么那段HTML标签就会被发送。
功能完整的HTTP服务器
这里,我们来开发一个具有完整功能的HTTP服务器,成为JHTTP,它可以提供一个完整的文档树,包括图片、applet、HTML文件、文本文件等等。它与SingleFileHTTPServer非常相似,只不过它所关注的是GET请求。此服务器仍然是相当轻量级的;看过这个代码后,我们将讨论可能希望添加的其他特性。
由于这个服务器必须为可能很慢的网络连接提供文件系统的大文件,因此要改变其方式。这里不再在执行主线程中处理到达的每个请求,而是将入站连接放入池中。由一个RequestProcessor类实例从池中移走连接并进行处理。
import&java.io.F &import&java.io.IOE &import&java.net.ServerS &import&java.net.S &&import&org.omg.CORBA.R &&&public&class&JHTTP&extends&Thread&{ &&&&&&private&File&documentRootD &&&&&private&String&indexFileName=&index.html&; &&&&&private&ServerSocket& &&&&&private&int&numThreads=50; &&&&& &&&&&public&JHTTP(File&documentRootDirectory,int&port&,&String&indexFileName)throws&IOException&{ &&&&&&&&&if&(!documentRootDirectory.isDirectory())&{ &&&&&&&&&&&&&throw&new&IOException(documentRootDirectory+&&does&not&exist&as&a&directory&&); &&&&&&&&&} &&&&&&&&&this.documentRootDirectory=documentRootD &&&&&&&&&this.indexFileName=indexFileN &&&&&&&&&this.server=new&ServerSocket(port); &&&&&} &&&&& &&&&&private&JHTTP(File&documentRootDirectory,&int&port)throws&IOException&{ &&&&&&&&&this(documentRootDirectory,&port,&&index.html&); &&&&&} &&&&& &&&&&public&void&run(){ &&&&&&&&&for&(int&i&=&0;&i&&&numT&i++)&{ &&&&&&&&&&&&&Thread&t=new&Thread(new&RequestProcessor(documentRootDirectory,&indexFileName)); &&&&&&&&&&&&&t.start(); &&&&&&&&&} &&&&&&&&& &&&&&&&&&System.out.println(&Accepting&connection&on&port&&&&&&&&&&&&&&&&&&&+server.getLocalPort()); &&&&&&&&&System.out.println(&Document&Root:&&+documentRootDirectory); &&&&&&&&&while&(true)&{ &&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&Socket&request=server.accept(); &&&&&&&&&&&&&&&&&RequestProcessor.processRequest(request); &&&&&&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&} &&&&&} &&&&& &&&&& &&&&&&&&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&File& &&&&&&&&&try&{ &&&&&&&&&&&&&docroot=new&File(args[0]); &&&&&&&&&}&catch&(ArrayIndexOutOfBoundsException&e)&{ &&&&&&&&&&&&&System.out.println(&Usage:&java&JHTTP&docroot&port&indexfile&); &&&&&&&&&&&&&return; &&&&&&&&&} &&&&&&&&& &&&&&&&&&int& &&&&&&&&&try&{ &&&&&&&&&&&&&port=Integer.parseInt(args[1]); &&&&&&&&&&&&&if&(port&0||port&65535)&{ &&&&&&&&&&&&&&&&&port=80; &&&&&&&&&&&&&} &&&&&&&&&}&catch&(Exception&e)&{ &&&&&&&&&&&&&port=80; &&&&&&&&&} &&&&&&&&& &&&&&&&&&try&{ &&&&&&&&&&&&&JHTTP&webserver=new&JHTTP(docroot,&port); &&&&&&&&&&&&&webserver.start(); &&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&System.out.println(&Server&could&not&start&because&of&an&&+e.getClass()); &&&&&&&&&&&&&System.out.println(e); &&&&&&&&&} &&&&&&&&& &&&&&} &&} &
JHTTP类的main()方法根据args[0]设置文档的根目录。端口从args[1]读取,或者使用默认的80.然后构造一个新的JHTTP线程并启动。此JHTTP线程生成50个RequestProcessor线程处理请求,每个线程在可用时从RequestProcessor池获取入站连接请求。JHTTP线程反复地接受入站连接,并将其放在RequestProcessor池中。每个连接由下例所示的RequestProcessor类的run()方法处理。此方法将一直等待,直到从池中得到一个Socket。一旦得到Socket,就获取输入和输出流,并链接到阅读器和书写器。接着的处理,除了多出文档目录、路径的处理,其他的同单文件服务器。
import&java.io.BufferedInputS &import&java.io.BufferedOutputS &import&java.io.DataInputS &import&java.io.F &import&java.io.FileInputS &import&java.io.IOE &import&java.io.InputStreamR &import&java.io.OutputS &import&java.io.OutputStreamW &import&java.io.R &import&java.io.W &import&java.net.S &import&java.util.D &import&java.util.L &import&java.util.LinkedL &import&java.util.StringT &&&public&class&RequestProcessor&implements&Runnable&{ &&&&&&private&static&List&pool=new&LinkedList(); &&&&&private&File&documentRootD &&&&&private&String&indexFileName=&index.html&; &&&&& &&&&&public&RequestProcessor(File&documentRootDirectory,String&indexFileName)&{ &&&&&&&&&if&(documentRootDirectory.isFile())&{ &&&&&&&&&&&&&throw&new&IllegalArgumentException(); &&&&&&&&&} &&&&&&&&&this.documentRootDirectory=documentRootD &&&&&&&&&try&{ &&&&&&&&&&&&&this.documentRootDirectory=documentRootDirectory.getCanonicalFile(); &&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&} &&&&&&&&& &&&&&&&&&if&(indexFileName!=null)&{ &&&&&&&&&&&&&this.indexFileName=indexFileN &&&&&&&&&} &&&&&} &&&&& &&&&&public&static&void&processRequest(Socket&request)&{ &&&&&&&&&synchronized&(pool)&{ &&&&&&&&&&&&&pool.add(pool.size(),request); &&&&&&&&&&&&&pool.notifyAll(); &&&&&&&&&} &&&&&} &&&&& &&&&&@Override&&&&&public&void&run()&{ &&&&&&&&&&&&&&&&&&String&root=documentRootDirectory.getPath(); &&&&&&&&& &&&&&&&&&while&(true)&{ &&&&&&&&&&&&&Socket& &&&&&&&&&&&&&synchronized&(pool)&{ &&&&&&&&&&&&&&&&&while&(pool.isEmpty())&{ &&&&&&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&&&&&pool.wait(); &&&&&&&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{ &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&connection=(Socket)pool.remove(0); &&&&&&&&&&&&&} &&&&&&&&&&&&& &&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&String&fileN &&&&&&&&&&&&&&&&&String&contentT &&&&&&&&&&&&&&&&&OutputStream&raw=new&BufferedOutputStream(connection.getOutputStream()); &&&&&&&&&&&&&&&&&Writer&out=new&OutputStreamWriter(raw); &&&&&&&&&&&&&&&&&Reader&in=new&InputStreamReader(new&BufferedInputStream(connection.getInputStream()),&&ASCII&); &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&StringBuffer&request=new&StringBuffer(80); &&&&&&&&&&&&&&&&&while&(true)&{ &&&&&&&&&&&&&&&&&&&&&int&c=in.read(); &&&&&&&&&&&&&&&&&&&&&if&(c=='\t'||c=='\n'||c==-1)&{ &&&&&&&&&&&&&&&&&&&&&&&&&break; &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&request.append((char)c); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&String&get=request.toString(); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(get); &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&StringTokenizer&st=new&StringTokenizer(get); &&&&&&&&&&&&&&&&&String&method=st.nextToken(); &&&&&&&&&&&&&&&&&String&version=&&; &&&&&&&&&&&&&&&&&if&(method==&GET&)&{ &&&&&&&&&&&&&&&&&&&&&fileName=st.nextToken(); &&&&&&&&&&&&&&&&&&&&&if&(fileName.endsWith(&/&))&{ &&&&&&&&&&&&&&&&&&&&&&&&&fileName+=indexFileN &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&contentType=guessContentTypeFromName(fileName); &&&&&&&&&&&&&&&&&&&&&if&(st.hasMoreTokens())&{ &&&&&&&&&&&&&&&&&&&&&&&&&version=st.nextToken(); &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&File&theFile=new&File(documentRootDirectory,fileName.substring(1,fileName.length())); &&&&&&&&&&&&&&&&&&&&&if&(theFile.canRead()&&theFile.getCanonicalPath().startsWith(root))&{ &&&&&&&&&&&&&&&&&&&&&&&&&DataInputStream&fis=new&DataInputStream(new&BufferedInputStream(new&FileInputStream(theFile))); &&&&&&&&&&&&&&&&&&&&&&&&&byte[]&theData=new&byte[(int)theFile.length()]; &&&&&&&&&&&&&&&&&&&&&&&&&fis.readFully(theData); &&&&&&&&&&&&&&&&&&&&&&&&&fis.close(); &&&&&&&&&&&&&&&&&&&&&&&&&if&(version.startsWith(&HTTP&&))&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&HTTP/1.0&200&OK\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&Date&now=new&Date(); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Date:&&+now+&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Server:&JHTTP&1.0\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Content-length:&&+theData.length+&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Content-Type:&&+contentType+&\r\n\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&&&&raw.write(theData); &&&&&&&&&&&&&&&&&&&&&&&&&raw.flush(); &&&&&&&&&&&&&&&&&&&&&}else&{ &&&&&&&&&&&&&&&&&&&&&&&&&if&(version.startsWith(&HTTP&&))&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&HTTP/1.0&404&File&Not&Found\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&Date&now=new&Date(); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Date:&&+now+&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Server:&JHTTP&1.0\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Content-Type:&text/html\r\n\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&HTML&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&HEAD&&TITLE&File&Not&Found&/TITLE&&/HRAD&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&BODY&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&H1&HTTP&Error&404:&File&Not&Found&/H1&&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&&/BODY&&/HTML&\r\n&); &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&}else&{&&&&&&&&&&&&&&&&&&&&&if&(version.startsWith(&HTTP&&))&{ &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&HTTP/1.0&501&Not&Implemented\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&Date&now=new&Date(); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Date:&&+now+&\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Server:&JHTTP&1.0\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.write(&Content-Type:&text/html\r\n\r\n&); &&&&&&&&&&&&&&&&&&&&&&&&&out.flush(); &&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&out.write(&&HTML&\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&&HEAD&&TITLE&Not&Implemented&/TITLE&&/HRAD&\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&&BODY&\r\n&); &&&&&&&&&&&&&&&&&&&&&out.write(&&H1&HTTP&Error&501:&Not&Implemented&/H1&&); &&&&&&&&&&&&&&&&&&&&&out.write(&&/BODY&&/HTML&\r\n&); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&}&catch&(IOException&e)&{ &&&&&&&&&&&&&}finally{ &&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&connection.close(); &&&&&&&&&&&&&&&&&}&catch&(IOException&e2)&{ &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&} &&&&&&&&&} &&&&&} &&&&& &&&&&public&static&String&guessContentTypeFromName(String&name)&{ &&&&&&&&&if&(name.endsWith(&.html&)||name.endsWith(&.htm&))&{ &&&&&&&&&&&&&return&&text/html&; &&&&&&&&&}else&if&(name.endsWith(&.txt&)||name.endsWith(&.java&))&{ &&&&&&&&&&&&&return&&text/plain&; &&&&&&&&&}else&if&(name.endsWith(&.gif&))&{ &&&&&&&&&&&&&return&&image/gif&; &&&&&&&&&}else&if&(name.endsWith(&.class&))&{ &&&&&&&&&&&&&return&&application/octet-stream&; &&&&&&&&&}else&if&(name.endsWith(&.jpg&)||name.endsWith(&.jpeg&))&{ &&&&&&&&&&&&&return&&image/jpeg&; &&&&&&&&&}else&{ &&&&&&&&&&&&&return&&text/plain&; &&&&&&&&&} &&&&&} &&} &
不足与改善:
这个服务器可以提供一定的功能,但仍然十分简单,还可以添加以下的一些特性:
(1) 服务器管理界面
(2) 支持CGI程序和Java Servlet API
(3) 支持其他请求方法
(4) 常见Web日志文件格式的日志文件
(5) 支持多文档根目录,这样各用户可以有自己的网站
最后,花点时间考虑一下可以采用什么方法来优化此服务器。如果真的希望使用JHTTP运行高流量的网站,还可以做一些事情来加速此服务器。第一点也是最重要的一点就是使用即时编译器(JIT),如HotSpot。JIT可以将程序的性能提升大约一个数量级。第二件事就是实现智能缓存。记住接受的请求,将最频繁的请求文件的数据存储在Hashtable中,使之保存在内存中。使用低优先级的线程更新此缓存。
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条头条头条头条热点
24H热文一周话题本月最赞
讲师:51278人学习过
讲师:12592人学习过
讲师:14974人学习过
精选博文论坛热帖下载排行
本书是一本介绍当前主流计算机网络应用技术的工具图书,全面总结了当前最主流、最基础的计算机网络应用,包括局域网和互联网应用两方面。在...
订阅51CTO邮刊

我要回帖

更多关于 恋与制作人 的文章

 

随机推荐