第2章:Tomcat

2.1 Web Server

Web Server也叫网页服务器,作用是发布资源,并提供对外的服务,所以也叫中间件,它只能对特定的磁盘内容进行发布,可以发布静态资源(例如html)和动态资源(例如应用程序)

2.2 JAVA EE

JAVA EE是一堆技术的总称,提供了一些难题的解决方案,只是方案,没有实现,也就是说是一堆接口

  1. Servlet:Server Applet,就是服务端上的小程序,用于动态的生成页面
  2. JDBC:用于操作数据库
  3. JSP:用于方便的编写页面代码
  4. JTA:用于解决事务控制的方案
  5. EJB:和SPRING是基本相似的,一直在比较着进步,EJB国内一般没人用。
  6. RMI:调用远程设备上的程序
2.3 Web Server分类

根据对JAVA EE支持的程度分为两大类,因为sun只提供了接口,真正实现webserver本身

  1. JAVA EE服务器:把除了JDBC以外的javaEE功能都实现了,JDBC由数据库厂商实现
    1. Weblogic
    2. JBoss
    3. geronimo
    4. websphere
  2. Web容器:只实现了servlet和jsp
    1. Tomcat
    2. jetty
2.4 Tomcat安装
  1. exe文件:但是只是解压,没有任何添加
  2. rar文件:尽量不要存放在含有中文的目录下
  3. 配置环境变量:
    1. CATALINA_HOME:E:\Program Files\apache-tomcat-7.0.100
    2. JAVA_HOME:E:\Program Files (x86)\Java\jdk1.8.0_221\bin
    3. JRE_HOME:E:\Program Files (x86)\Java\jre1.8.0_221
2.5 Tomcat目录结构
  1. bin:存放启动关闭脚本
    1. startup.bat:
      1. 启动脚本,启动后浏览器输入http://localhost:8080,可以看到页面
      2. 右上角关闭时,不一定每次都能正确关闭,再次启动可能会失败,需要人为杀掉虚拟机进程java.exe
    2. shutdown.bat:关闭脚本
  2. conf:存放配置文件
  3. lib:存放Tomcat所依赖的jar包
  4. logs:存放日志,catalina.log为控制台日志
  5. temp:临时的数据文件,里面东西可以删,文件夹不能删
  6. webapps:存放web应用,里面就是想对外发布的资源
    1. ROOT:输入url和端口号,但是没有输入uri(具体资源)时,默认进到ROOT打开index.jsp
  7. work:存放JSP被编译成的.class文件的存放位置。例:ROOT下的index.jsp被编译成index_jsp.class后存放于work\Catalina\localhost_\org\apache\jsp中
2.6 server.xml配置文件详解
<?xml version="1.0" encoding="UTF-8"?>
<!--根节点为Server,其实就是启了一个ServerSocket,一个Server就是是一个ServerSocket的实例,这个ServerSocket用于监听8005端口,用于接收shutdown命令关闭tomcat -->
<Server port="8005" shutdown="SHUTDOWN">
	<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
	<Listener SSLEngine="on"
		className="org.apache.catalina.core.AprLifecycleListener" />
	<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
	<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
	<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
	<GlobalNamingResources>
		<Resource auth="Container" description="User database that can be updated and saved"
			factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase"
			pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase" />
	</GlobalNamingResources>
	<!--Service表示能够处理请求的一个服务 -->
	<Service name="Catalina">
		<!--Connector表示一个Service可以处理多种请求,tomcat启动后会先启动server,再启动service, 再启动多个Connector,用于监听不同的端口 -->
		<!--此处表示tomcat启动8080端口,只用于处理http协议的请求, 超时时间为20000ms,即连接请求等待超过这个时间,没有被处理的请求,返回超时 -->
		<!-- 如果为https协议, 转发到端口8443,https为安全协议,会对请求的表单中加密,如果想使用https服务, 需要自己写证书(jdk/bin/keytool.exe可以生成证书) -->
		<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
			redirectPort="8443" />
		<!--AJP是一个不是很常用的协议 -->
		<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
		<!--Engine处理Connector收到的请求,将请求发给Host进行处理,先将uri中的主机地址与所有Host挨个匹配,如果都匹配不到转发给名为localhost的Host进行处理 -->
		<Engine defaultHost="localhost" name="Catalina">
			<Realm className="org.apache.catalina.realm.LockOutRealm">
				<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
					resourceName="UserDatabase" />
			</Realm>
			<Host appBase="webapps" autoDeploy="true" name="localhost"
				unpackWARs="true">
				<Valve className="org.apache.catalina.valves.AccessLogValve"
					directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log"
					suffix=".txt" />
			</Host>
			<!--可以新加一个Host这样可以当访问本机ip时,如果使用不同的域名,会访问不同的资源,这种配置方法也叫配置虚拟主机, 一个Host就是一个虚拟的主机 -->
			<!--例如:zhidao.baidu.com和baidu.com其实都是同样的ip只不过域名不同 -->
			<!--系统解析域名时会先访问文件C:\Windows\System32\drivers\etc\hosts,如果没有对应的域名解析,才会去DNS服务器找,为了不让DNS服务器解析我们的域名, 
				修改hosts文件 -->
			<!--在tomcat根目录下创建ceshi文件夹,这个文件夹下也必须再创建个文件夹,例wsh,里面放入你的资源例index.html,此时可以通过浏览器输入http://www.wsh.com:8080/wsh/index.html访问该资源 -->
			<Host name="www.wsh.com" appBase="ceshi" unpackWARs="true"
				autoDeploy="true" />
		</Engine>
	</Service>
</Server>
2.7 tomcat项目部署
2.7.1 部署的方式
  1. 静态部署:tomcat必须重启
  2. 动态部署:tomcat无需重启
2.7.2 三种静态部署方式
  1. 直接往webapps放资源
  2. 修改server.xml:这样部署允许你使用webapps以外的磁盘资源
<!--重启tomcat后,在浏览器上输入http://localhost:8080/hello/index.html进行访问-->
<Host appBase="webapps" autoDeploy="true" name="localhost"
	unpackWARs="true">
	<!--即在Host中加入Context节点,注意path后必须有"/", 否则报错-->
	<!--下面配置相当于建立了一个目录的映射,如果浏览器中访问/hello那么意味着访问服务器上的"D:/workspace"-->
	<Context path="/hello" docBase="D:/workspace" debug="0"
		privileged="true"></Context>
	<Valve className="org.apache.catalina.valves.AccessLogValve"
		directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log"
		suffix=".txt" />
</Host>
  1. conf\Catalina\localhost下建立hello.xml:也允许将资源放在webapps外部
<!--重启tomcat后,在浏览器上输入http://localhost:8080/hello/index.html进行访问-->
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/hello" docBase="D:/workspace" debug="0"
	privileged="true"></Context>
2.7.3 动态部署:必须在tomcat管理界面完成
  1. 配置密码:修改D:\apache-tomcat-7.0.81\conf\tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
    <!--role标签标示开启决策,以下为各决策权限-->
    <!--
    manager-gui - allows access to the HTML GUI and the status pages
    manager-script - allows access to the text interface and the status pages
    manager-jmx - allows access to the JMX proxy and the status pages
    manager-status - allows access to the status pages only
    -->
	<role rolename="manager-gui" />
	<role rolename="manager-script" />
	<!--user标签标示建立用户分配角色-->
	<user username="tomcat" password="tomcat" roles="manager-gui,manager-script" />
</tomcat-users>
  1. 进入管理界面:
http://localhost:8080
  1. Manager App
  2. 填写页面内容:其实就是修改配置文件,增加Context
    1. ontext Path (required):/oldlu
    2. WAR or Directory URL:D:\oldlu
    3. 点击deploy
  3. 通过浏览器访问D:\oldlu下的1.html
http://localhost:8080/oldlu/1.html
2.8 手动实现Tomcat
  1. Tomcat处理流程
    在这里插入图片描述
  2. MyRequest:用于接收HTTP请求,并转为MyRequest对象
import java.io.IOException;
import java.io.InputStream;

public class MyRequest {
    private String requestMethod;
    private String requestUrl;

    public MyRequest(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        String str = null;
        if((len=inputStream.read(buffer))>0){
            str = new String(buffer,0,length);
        }
        // GET / HTTP/1.1
        String data = str.split("\n")[0];
        String[] params = data.split(" ");
        this.requestMethod = params[0];
        this.requestUrl = params[1];
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }
}

  1. MyResponse:用于返回HTTP响应
import java.io.IOException;
import java.io.OutputStream;

public class MyResponse {
    private OutputStream outputStream;

    public MyResponse(OutputStream outputStream) {
        this.outputStream = outputStream;
    }
    //用于返回响应给浏览器
    public void write(String str) throws IOException {
        StringBuilder builder = new StringBuilder();
        builder.append("HTTP/1.1 200 OK\n")
                .append("Content-Type:text/html\n")
                .append("\r\n")
                .append("<html>")
                .append("<body>")
                .append("<h1>"+str+"</h1>")
                .append("</body>")
                .append("</html>");
        this.outputStream.write(builder.toString().getBytes());
        this.outputStream.flush();
        this.outputStream.close();

    }
}

  1. MyMapping:配置uri与Servlet映射关系
import java.util.HashMap;

public class MyMapping {
    public static HashMap<String,String> mapping = new HashMap<String,String>();
    static{
        mapping.put("/mytomcat","MyServlet");
    }
    public HashMap<String,String> getMapping(){
        return mapping;
    }
}

  1. MyHttpServlet:接口或抽象类,这样就可以利用多态,调用不同Servlet时,doGet有不同的实现。service方法判断调用哪个请求方法
import java.io.IOException;

public abstract class MyHttpServlet {
    public static final String METHOD_GET = "GET";
    public static final String METHOD_POST = "GET";

    public abstract void doGet(MyRequest request, MyResponse response) throws IOException;

    public abstract void doPost(MyRequest request, MyResponse response) throws IOException;

    public void service(MyRequest request, MyResponse response) throws IOException {
        if (METHOD_GET.equals(request.getRequestMethod())) {
            doGet(request, response);
        } else if (METHOD_POST.equals(request.getRequestMethod())) {
            doPost(request, response);
        }
    }
}

  1. MyServlet:具体的请求方法的实现
import java.io.IOException;

public class MyServlet extends MyHttpServlet{
    @Override
    public void doGet(MyRequest request, MyResponse response) throws IOException {
        response.write("get tomcat");
    }

    @Override
    public void doPost(MyRequest request, MyResponse response) throws IOException {
        response.write("post tomcat");
    }
}

  1. MyServer:建立长连接,接收请求后分派给指定的Servlet
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
    public static void startServer(int port) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        ServerSocket ss = new ServerSocket(port);
        while (true) {
            Socket s = ss.accept();
            MyRequest request = new MyRequest(s.getInputStream());
            MyResponse response = new MyResponse(s.getOutputStream());
            String clazz = new MyMapping().getMapping().get(request.getRequestUrl());
            if (clazz != null) {
                Class<MyHttpServlet> myHttpServletClass = (Class<MyHttpServlet>) Class.forName(clazz);
                MyHttpServlet myHttpServlet = myHttpServletClass.newInstance();
                myHttpServlet.service(request, response);
            }
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
        startServer(8080);
    }
}

发布了32 篇原创文章 · 获赞 0 · 访问量 931

猜你喜欢

转载自blog.csdn.net/hanzong110/article/details/104390435
今日推荐