tomcat4源码剖析(二)——简单的Servlet容器

万字深度剖析Tomcat源码 (全是干货,建议收藏!!!) Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。 阅读详情

好久没有写博客了,最近要毕业了,写论文写的好烦。然后就又拿起了这本《深入剖析tomcat》来看一看。 哎,希望今年能顺利毕业。

其实本篇也就是对《深入理解tomcat》中第二章第一个简单的servlet容器的代码进行分析。

一、简单Servlet容器的功能

本篇所构建的Servlet功能如下:
1,解析请求的url,将url封装成一个自定义的Request。解析包括对请求服务器资源名称的解析。
2,接收浏览器的请求,根据请求的URL的类型。选择是加载一个Servlet类还是返回系统的静态文件。当URL中包含/servlet/关键路径时,加载指定的Servlet,当不包含时,加载静态文件。
3,若加载的是Servlet调用该Servlet的service()方法,当是静态文件的时候,直接返回文件。在传输完成后,关闭socket

二、系统类简介

  • HttpServer1:程序启动的总入口
  • Request :在接收到浏览器请求时,HttpServer1利用Request将请求进行包装
  • Response:对浏览器的回应封装
  • StaticResourceProcessor:处理静态资源的类
  • ServletProcessor1:处理请求是Servlet时的类
  • Constants:系统常量

三、代码结构


在src目录下,建立ex02.pyrmont包。同时在src同级目录下建立webroot目录,里面包含一个index.html静态资源以及一个编译好的Servlet。

三、源码解析

1,HttpServer1.java

package ex02.pyrmont;

import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class HttpServer1 {
  private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

  // the shutdown command received
  private boolean shutdown = false;

  public static void main(String[] args) {
    HttpServer1 server = new HttpServer1();
    server.await();
  }

  public void await() {
    ServerSocket serverSocket = null;
    int port = 8080;
    try {
      serverSocket =  new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
    }
    catch (IOException e) {
      e.printStackTrace();
      System.exit(1);
    }

    while (!shutdown) {
      Socket socket = null;
      InputStream input = null;
      OutputStream output = null;
      try {
        socket = serverSocket.accept();
        input = socket.getInputStream();
        output = socket.getOutputStream();

        // 将浏览器的请求封装成一个自定义的Request
        Request request = new Request(input);
        request.parse();

        // 建立一个相应类
        Response response = new Response(output);
        response.setRequest(request);

        // 通过上面Request解析后的URl判断该URI中是否包含“/servlet/”路径,如果有,调用ServletProcessor1类相应
        //浏览器,如果没有,调用StaticResourceProcessor相应浏览器
        if (request.getUri().startsWith("/servlet/")) {
          ServletProcessor1 processor = new ServletProcessor1();
          processor.process(request, response);
        }
        else {
          StaticResourceProcessor processor = new StaticResourceProcessor();
          processor.process(request, response);
        }

        // 在回复浏览器后,关闭与浏览器产生联系的套接字
        socket.close();
        //判断一下浏览器指令是否为关闭服务器
        shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
      }
      catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
      }
    }
  }
}

        在HttpServer1中启动后,主要是调用await()方法,在该方法中建立一个serverSocket。用来监控本地的8080端口,在接收到浏览器的请求后,创建Request对象将浏览器请求封装。然后通过请求的URL判断是请求的静态文件还是Servlet。最后关闭socket。

2,Request.java 源码如下

package ex02.pyrmont;

import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import javax.servlet.*;


public class Request implements ServletRequest {

  private InputStream input;
  private String uri;

  public Request(InputStream input) {
    this.input = input;
  }

  public String getUri() {
    return uri;
  }

  // 解析传递过来的URI,形如: GET /servlet/PrimitiveServlet HTTP/1.1
  private String parseUri(String requestString) {
    int index1, index2;
    index1 = requestString.indexOf(' ');
    if (index1 != -1) {
      index2 = requestString.indexOf(' ', index1 + 1);
      if (index2 > index1)
        return requestString.substring(index1 + 1, index2);
    }
    return null;
  }

// 从建立的socket中获取浏览器传送过来的信息,其实就是tomcat4源码剖析(一)中讲到的一般请求过程
  public void parse() {
    // Read a set of characters from the socket
    StringBuffer request = new StringBuffer(2048);
    int i;
    byte[] buffer = new byte[2048];
    try {
      i = input.read(buffer);
    }
    catch (IOException e) {
      e.printStackTrace();
      i = -1;
    }
    for (int j=0; j<i; j++) {
      request.append((char) buffer[j]);
    }
    // request中就是浏览器传递过来的东西
    System.out.print(request.toString());
    uri = parseUri(request.toString()); // 解析浏览器传递过来的URI
  }

   //之后添加的是继承ServletRequest需要实现的方法,暂时不需要管
  /* implementation of the ServletRequest*/
  public Object getAttribute(String attribute) {
    return null;
  }

  public Enumeration getAttributeNames() {
    return null;
  }

  public String getRealPath(String path) {
    return null;
  }

  public RequestDispatcher getRequestDispatcher(String path) {
    return null;
  }

  public boolean isSecure() {
    return false;
  }

  public String getCharacterEncoding() {
    return null;
  }

  public int getContentLength() {
    return 0;
  }

  public String getContentType() {
    return null;
  }

  public ServletInputStream getInputStream() throws IOException {
    return null;
  }

  public Locale getLocale() {
    return null;
  }

  public Enumeration getLocales() {
    return null;
  }

  public String getParameter(String name) {
    return null;
  }

  public Map getParameterMap() {
    return null;
  }

  public Enumeration getParameterNames() {
    return null;
  }

  public String[] getParameterValues(String parameter) {
    return null;
  }

  public String getProtocol() {
    return null;
  }

  public BufferedReader getReader() throws IOException {
    return null;
  }

  public String getRemoteAddr() {
    return null;
  }

  public String getRemoteHost() {
    return null;
  }

  public String getScheme() {
   return null;
  }

  public String getServerName() {
    return null;
  }

  public int getServerPort() {
    return 0;
  }

  public void removeAttribute(String attribute) {
  }

  public void setAttribute(String key, Object value) {
  }

  public void setCharacterEncoding(String encoding)
    throws UnsupportedEncodingException {
  }

  @Override
  public long getContentLengthLong() {
    return 0;
  }

  @Override
  public int getRemotePort() {
    return 0;
  }

  @Override
  public String getLocalName() {
    return null;
  }

  @Override
  public String getLocalAddr() {
    return null;
  }

  @Override
  public int getLocalPort() {
    return 0;
  }

  @Override
  public ServletContext getServletContext() {
    return null;
  }

  @Override
  public AsyncContext startAsync() throws IllegalStateException {
    return null;
  }

  @Override
  public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
    return null;
  }

  @Override
  public boolean isAsyncStarted() {
    return false;
  }

  @Override
  public boolean isAsyncSupported() {
    return false;
  }

  @Override
  public AsyncContext getAsyncContext() {
    return null;
  }

  @Override
  public DispatcherType getDispatcherType() {
    return null;
  }
}

        在Request类中,主要就做了一件事将如下字符串进行解析,并将其中的URI赋值给Request类中的uri变量。

GET /servlet/PrimitiveServlet HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

3, Response.java

package ex02.pyrmont;

import java.io.OutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.File;
import java.io.PrintWriter;
import java.util.Locale;
import javax.servlet.ServletResponse;
import javax.servlet.ServletOutputStream;

public class Response implements ServletResponse {

  private static final int BUFFER_SIZE = 1024;
  Request request;
  OutputStream output;
  PrintWriter writer;

  public Response(OutputStream output) {
    this.output = output;
  }

  public void setRequest(Request request) {
    this.request = request;
  }

  /* This method is used to serve a static page */
  public void sendStaticResource() throws IOException {
    byte[] bytes = new byte[BUFFER_SIZE];
    FileInputStream fis = null;
    try {
      /* request.getUri has been replaced by request.getRequestURI */
      File file = new File(Constants.WEB_ROOT, request.getUri());
      fis = new FileInputStream(file);
      /*
         HTTP Response = Status-Line
           *(( general-header | response-header | entity-header ) CRLF)
           CRLF
           [ message-body ]
         Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
      */
      int ch = fis.read(bytes, 0, BUFFER_SIZE);
      while (ch!=-1) {
        output.write(bytes, 0, ch);
        ch = fis.read(bytes, 0, BUFFER_SIZE);
      }
    }
    catch (FileNotFoundException e) {
      String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
        "Content-Type: text/html\r\n" +
        "Content-Length: 23\r\n" +
        "\r\n" +
        "<h1>File Not Found</h1>";
      output.write(errorMessage.getBytes());
    }
    finally {
      if (fis!=null)
        fis.close();
    }
  }


  /** implementation of ServletResponse  */
  public void flushBuffer() throws IOException {
  }

  public int getBufferSize() {
    return 0;
  }

  public String getCharacterEncoding() {
    return null;
  }

  public Locale getLocale() {
    return null;
  }

  public ServletOutputStream getOutputStream() throws IOException {
    return null;
  }

  public PrintWriter getWriter() throws IOException {
    // autoflush is true, println() will flush,
    // but print() will not.
    writer = new PrintWriter(output, true);
    return writer;
  }

  public boolean isCommitted() {
    return false;
  }

  public void reset() {
  }

  public void resetBuffer() {
  }

  public void setBufferSize(int size) {
  }

  public void setContentLength(int length) {
  }

  public void setContentType(String type) {
  }

  public void setLocale(Locale locale) {
  }

    public String getContentType() {
        return null;
    }

    public void setCharacterEncoding(String s) {

    }

    public void setContentLengthLong(long l) {

    }
}

Response类中最主要的就是sendStaticResource()方法,主要是在根据浏览器请求的是静态文件时,供StaticResourceProcessor类调用。在查找静态资源时,如果没有找到,则返回404页面。
4,ServletProcessor1.java

package ex02.pyrmont;

import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.io.File;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletProcessor1 {

  public void process(Request request, Response response) {

    String uri = request.getUri();
    String servletName = uri.substring(uri.lastIndexOf("/") + 1); //找到具体所要请求的servlet名字
    URLClassLoader loader = null; //类加载器

    try {
      // 创建类加载器
      URL[] urls = new URL[1];
      URLStreamHandler streamHandler = null;
      File classPath = new File(Constants.WEB_ROOT);
      String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
      urls[0] = new URL(null, repository, streamHandler);
      loader = new URLClassLoader(urls);
    }
    catch (IOException e) {
      System.out.println(e.toString() );
    }
    Class myClass = null;
    try {
      //加载相应的servlet.class文件
      myClass = loader.loadClass(servletName);
    }
    catch (ClassNotFoundException e) {
      System.out.println(e.toString());
    }

    Servlet servlet = null;

    try {
      // 创建Servlet实例
      servlet = (Servlet) myClass.newInstance();
      // 调用Servlet的service()方法
      servlet.service((ServletRequest) request, (ServletResponse) response);
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
    catch (Throwable e) {
      System.out.println(e.toString());
    }

  }
}

ServletProcessor1的主要作用是根据指定的servlet名称找到对应的资源利用反射创建对应的servlet实例。然后调用实例的service()方法。
5,StaticResourceProcessor.java

package ex02.pyrmont;

import java.io.IOException;

public class StaticResourceProcessor {

  public void process(Request request, Response response) {
    try {
      response.sendStaticResource();// 调用response的静态方法
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

6,Constants.java

package ex02.pyrmont;

import java.io.File;

public class Constants {
  public static final String WEB_ROOT =
    System.getProperty("user.dir") + File.separator  + "webroot";
}

WEB_ROOT 在本机上就是D:\F\IDEA程序\Tomcat\webroot路径。

6,PrimitiveServlet.java

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class PrimitiveServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        PrintWriter out = servletResponse.getWriter();
        out.println("HTTP/1.1 200 OK"); // 记住一定要加上这一句哦
        out.println("Server: zkw");
        out.println();
        out.println("<html>");
        out.println("Learning how tomcat works");
        out.println("</html>");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

7,index.html

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
<head>
<title>Welcome to BrainySoftware</title>
</head>
<body>
<br>
Welcome to BrainySoftware.
</body>
</html>

注意要加上前面的三行。

四、其他

1,运行
在浏览器输入
http://localhost:8080/servlet/PrimitiveServlet 之后,出现如下图片
在这里插入图片描述
在浏览器输入http://localhost:8080/index.html 后出现如下图片
在这里插入图片描述
2 建议
第三节中代码为完整代码,可以直接复制到自己工程项目中运行。同时也上传了项目的完整代码,下载地址:https://download.youkuaiyun.com/download/tyoukai_/11019831

建议自己跑一下,以调试的模式,单步看看程序执行结果。
以上就是最简单的Servlet容器了。Tomcat在此基础上进行了很多扩展,但是原理都是一样的。

Tomcat系统架构与原理剖析及手写Tomcat及源码导入学习 阅读详情

相关推荐

Tomcat 8源代码 Servlet源代码

tomcat源码,servlet源码,简单实用

Tomcat Servlet request.getRemoteAddr()所得值为0:0:0:0:0:0:0:1

环境: tomcat5.6 JSP UTF-8 IP协议:IPv4,IPv6 服务器和访问者在同一机器上。 问题描述 上传文件时,为了避免文件名重复,打算利用IP地址+时间戳的方式和给文件命名。但是,从本机上访问本机服务器时,利用request.getRemoteAddr()函数获取IP地址,得到的是0:0:0:0:0:0:0:1。因为是按IPv4的方...

飞龙YF的博客 491

tomcat4.0源码

tomcat4.1.12源码,想要了解tomcat初始版本的源码看以看看

【tomcat源码分析】tocmat工作原理

分成selvet请求处理部分和网络连接connnector部分 执行请求流程 一、servlet 四大selvet容器 Engine host context wrapper 二、connnector endpoint processor adapter tomcat的io模型

sumengnan的博客 650

tomcat4 源码学习,深度剖析tomcat一书的指定tomcat版本,欢迎大家下载,官网下载会出现下载不了的情况,

tomcat4 源码学习,深度剖析tomcat一书的指定tomcat版本,随着tomcat版本的升级,内容发生 了变化,但为了读懂书籍,还是得使用老版本得源码,欢迎大家下载,官网下载会出现下载不了的情况,我主页有tomcat4-tomcat9所有版本源码,之前去官网下载,发现每次都下载不了,后来主动收集了全版本的源码,供大家学习。

项目-tomcat4

项目-tomcat3

Tomcat4.1.24源码分析导引

  1 前言Tomcat是一个servlet容器,它是Java Servlet和JavaServer Pages技术的官方参考实现。Tomcat是在Apache Software License下开发和发布的一个开放源码的项目。在本文做成时Tomcat的主要版本是Tomcat 5.0.2 Alpha版实现了Servlet2.4/JSP2.0规范和Tomcat4.1.24版实现了Servle

赵晨希的Blog 871

tomcatweb:servlet规范servlet容器tomcat源码研究

本项目做tomcat源码研究 主页 http://tomcat.apache.org/index.html 研究环境: Server.服务器版本: Apache Tomcat/9.0.30 OS Name: Windows 10 OS.版本: 10.0 架构: amd64 JVM 版本: 1.8.0_221-b11 JVM.供应商: Oracle Corporation IDE idea2019 第一个问题--idea控制台乱码 ### 乱码解决 tomcat conf下logging.properties设置文件编码 其中由如下一行,默认utf-8 java.util.logging.ConsoleHandler.encoding = G

Java Tomcat SRC 下载地址

Java Tomcat SRC 下载地址: http://apache.dataguru.cn/tomcat/

huangzhen0914的专栏 681

OriginPro实战:5步搞定碳材料拉曼光谱D峰G峰分析(附完整数据处理流程)

本文详细介绍了使用OriginPro进行碳材料拉曼光谱D峰G峰分析的完整流程,涵盖数据预处理、多图层可视化、高精度分峰拟合等关键步骤。特别针对材料科学研究中的基线漂移、多峰重叠等问题提供专业解决方案,帮助研究者快速完成从原始数据到科研级图表的全流程分析,提升碳材料表征效率与准确性。

vodka的博客 942

【学习路线】 游戏客户端开发入门到进阶

游戏开发是一个交叉性极强的技术领域,对开发者提出了高维度的要求。作为初学者,不要急于求成,打牢基础、注重原理、勤于实践,你的成长将会非常快速而稳健。希望这份学习路线与书单能为你指明方向,迈出职业开发者的第一步。

hhw_hhw的博客 2127

Tomcat容器结构 = 四大容器 + 连接器

Tomcat容器结构 = 四大容器 + 连接器。

童小绿 学无止境 1299

探索robotics-toolbox-python:从基础安装到高级机器人运动学应用

本文详细介绍了robotics-toolbox-python工具箱,从基础安装、环境配置到机器人运动学与动力学的核心应用。通过D-H参数、URDF导入和内置模型三种方式快速构建机器人模型,并演示了正逆运动学计算、关节空间与任务空间轨迹规划以及三维可视化仿真。该工具箱极大地简化了机器人算法开发流程,是进行机器人学研究和应用实践的强大工具。

i1j2k的博客 496

深入剖析Tomcat(二) 实现一个简单的Servlet容器

Tomcat造轮子,整个简单的Servlet容器

咖啡煮码 1336

基于QEMU的openEuler aarch64虚拟机快速部署与漏洞验证指南

本文提供了一份基于QEMU在个人电脑上快速部署openEuler aarch64虚拟机的详细指南。内容涵盖从软件准备、目录规划、QEMU安装、虚拟磁盘创建到系统安装与SSH配置的全过程,并以CVE-2024-1086内核漏洞为例,演示了如何在该虚拟环境中进行安全漏洞的验证与补丁测试,为安全研究和运维测试提供了一个低成本、高效率的ARM架构沙箱环境。

earth的博客 438

AI写作:为AI人工智能领域赋能

AI写作技术作为自然语言处理(NLP)领域的重要应用方向,正在深刻改变内容创作的方式。系统介绍AI写作的技术原理分析主流AI写作模型的架构特点提供实践性的代码示例探讨实际应用中的关键问题展望未来发展趋势本文涵盖从基础理论到高级应用的完整知识体系,适用于希望深入了解AI写作技术的开发者和研究人员。背景介绍:建立基本概念框架核心概念:解析关键技术原理算法实现:通过代码演示具体实现数学原理:深入底层数学模型实践应用:展示真实场景案例资源推荐:提供学习路径和工具。

AI天才研究院 3052

深入剖析tomcat之servlet容器

其实我们开发中经常用tomcat应用服务器,tomcat就一个servlet容器,能够运行基于serlvlet的应用程序并响应相应的http请求,开发时间长了,还是想想具体知道它是怎么运行的,尤其是servlet容器的机理,所以有幸拜读了外国人的《深入剖析tomcat》,感觉挺不错的,可以在此点击免费下载电子书,建议大家有时间读读,在读的过程中边读边翻阅着tomcat的源码,更有助于你理解它的各个

Java我人生的技术博客 7583

1个PID回路如何连接2个执行器(算法和代码)

我们先看下位置型PID的控制框图:2、PID是基于error的控制 所以反馈信号跳动、干扰非常大的话,对PID的闭环控制影响是非常大的,所以对于反馈信号、一定要抗干扰和滤波处理。3、下图是增量型PID的控制框图:4、一个PID输出回路如何连接2个执行器?(有些系统会设置热阀和冷阀才能满足控制要求)。

RXXW_Dor的博客 1810

Tomcat源码剖析笔记总结(超长干货——逐步分析)

主要分四部分: 套娃式架构设计 架构属于设计层次,源码是对设计的实现 Tomcat的架构设计比较独特,属于套娃式架构设计 源码剖析的原则、方法和技巧 Tomcat实例构建(启动过程源码分析) Servlet请求处理链路(Servlet如何被Tomcat处理的) 文章目录@[toc]一、Tomcat架构设计1.1 Tomcat的功能(需求)1.2 Tomcat的架构(架构就是为了完成功能...

zhuiyisinian的博客 5777

出现 has been blocked by CORS policy: No ‘Access-Control-Allow-Origin‘ header is present on the 解决方法

Access to XMLHttpRequest at 'http://127.0.0.1:5000/api/data' from origin 'http://10.197.0.79:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

码农研究僧的博客 1万+

linux v3h平台开发系列详解(GMSL摄像头篇):1.11 解串器MIPI 1.5G高速率特殊deskew配置

解串器max96712 deskew配置

xian18809311584的博客 1775

深入剖析Tomcat(五) 剖析Servlet容器并实现一个简易Context与Wrapper容器

Tomcat中Servlet容器之Context、Wrapper容器

咖啡煮码 1631

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Tomcat 容器(Container)体系源码剖析

四层结构请求流转:逐层匹配,最终定位 ServletPipeline-Valve 机制:责任链模式,支持扩展核心源码容器是Tomcat 的请求调度核心,理解它的分层和 Pipeline 机制,才能真正掌握请求是如何一步步路由到 Servlet 的。

波波烤鸭的博客 1186

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Tomcat源码学习记录

一、官网下载Tomcat 的源码: 1、地址:http://tomcat.apache.org/ 左侧 Download Tomcat 7,在网页最下面下载Tomcat源码; 2、下载完成后打开 , 选择File->Open->选择tomcat的源码目录

qq_43012792的博客 1万+

tomcat源码分析之filter和servlet

学习JavaEE的时候,看的是尚学堂的视频。记得老师在介绍各种web服务器的时候,说tomcat其实应该叫做servlet容器。这一句话不说不要紧,一说就让我纠结了好几个月。当时老师讲JavaEE的时候并没有深入的讲tomcat。偶然间提到一次servlet的调用机制就觉得高贵冷艳。没有办法,当时知识有限,我只好以“tomcat本来就是servlet容器”自我安慰。 不过这种“美好生活”没有持续

intheworld 3066

SpringBoot-内嵌Tomcat源码剖析

Spring Boot 默认支持 Tomcat , Jetty ,和 Undertow 作为底层容器。而 Spring Boot 默认使用 Tomcat ,一旦引入 spring-boot-starter-web 模块,就默认使用 Tomcat 容器。

学英语的程序员 968
上一篇: tomcat4源码剖析(一)——tomcat的整体架构
下一篇: 美团cat服务器安装时显示“有问题的cat服务器”解决办法
TYOUKAI_
博客等级 码龄9年 33粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值