2. Tomcat、Web Server、JAVA EE

1 JAVA EE

  1. JAVA EE是一堆技术的总称,提供了一些难题的解决方案,只是方案,没有实现,也就是说是一堆接口
    1. Servlet:Server Applet,就是服务端上的小程序,用于动态的生成页面
    2. JDBC:用于操作数据库
    3. JSP:用于方便的编写页面代码
    4. JTA:用于解决事务控制的方案
    5. EJB:和SPRING是基本相似的,一直在比较着进步,EJB国内一般没人用
    6. RMI:调用远程设备上的程序

2 Web Server

  1. Web Server也叫网页服务器,作用是发布资源,并提供对外的服务,所以也叫中间件,它只能对特定的磁盘内容进行发布,可以发布静态资源(例如html)和动态资源(例如应用程序)
2.1 Web Server分类
  1. 根据Web Server对JAVA EE支持的程度,将Web Server分为两大类,sun只是提供了接口,真正实现Web Server本身
    1. JAVA EE服务器:把除了JDBC以外的javaEE功能都实现了,JDBC由数据库厂商实现
      1. Weblogic
      2. JBoss
      3. geronimo
      4. websphere
    2. Web容器:只实现了servlet和jsp
      1. Tomcat
      2. jetty

3 Tomcat

3.1 Tomcat安装
  1. exe文件:执行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
3.2 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中
3.3 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,即连接请求等待超过这个时间,没有被处理的请求,返回超时 -->
		<!-- 使用8443端口处理https协议的请求,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挨个匹配,如果都不匹配,转发给名defaultHost,也就是名为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文件将我们输入的域名解析为ip地址,如果没有对应的域名,才会使用DNS服务器解析,我们自己定义的域名肯定是在DNS服务器上找不到的,因此为了不让DNS服务器解析我们的域名,可以修改hosts文件,添加我们自定义的域名与ip的对照关系 -->
			<!--在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>
3.4 tomcat项目部署
3.4.1 部署的方式
  1. 静态部署:tomcat必须重启
  2. 动态部署:tomcat无需重启
3.4.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>
3.4.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. Context Path (required):/oldlu
    2. WAR or Directory URL:D:\oldlu
    3. 点击deploy
  3. 通过浏览器访问D:\oldlu下的1.html
http://localhost:8080/oldlu/1.html
3.5 手动实现Tomcat
  1. Tomcat处理流程
    在这里插入图片描述
  2. 整体思路:通过ServerSocket 监听某个端口,然后使用Socket可以获取HTTP请求的数据包的输入流和输出流,将输入流转为MyRequest t对象,将输出流转为MyResponse对象,之后根据url找到预先定义好的对应的类MyHttpServlet ,利用MyRequest t对象和MyResponse对象来构造MyHttpServlet对象,最后调用该对象的service方法
  3. 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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值