work:运行时生成的文件,最终运行的文件都在这里。通过webapps中的项目生成的!可以把这个目录下的内容删除,再次运行时会生再次生成work目录。当客户端用户访问一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。
通过这些目录就可以知道Tomcat的简单的结构.
那个运行的文件在work下,会引起tomcat的缓存的问题的,如果有遇到的话,建议将work目录下得Catalina这个删除掉即可了.这个目录下有运行的文件的,进入查看后会发现,jsp的文件会被编译为Servlet的,命名格式是这样的:例如index.jsp,会编译为index_jsp.java,字节码, index_jsp.class的.
在Eclipse中配置Tomcat可是比较简单的,关键是项目发布的位置了,如果直接new 一个server的,不打开修改一下路径的话,就会发布到Eclipse的克隆服务器的.如果是多个就会以temp0,temp1等的命名格式.会有一个wtpwebapps的目录,项目就会发布到那个在那的.打开Eclipse如果想发布到自己安装的那个tomcat中的webapps下就建议修改一下吧.
Server instance is not configured.
是无法解析Tomcat 下的Server.xml文件,不是没有写UTF-8的格式,而是最近打开了server.xml文件时,保存的时候是以文档格式的保存方式,修改为UTF-8的格式就可以了,这样Tomcat就可以解析server.xml格式的xml文件了,这样Tomcat就可以成功启动了;
tomcat的默认编码是ISO-8859-1的。如何修改才能是我们的get和post请求不发生乱码呐?(乱码的原因可以归结为一句话,发送过去服务端的和要显示在客户端的不是编码格式不统一!)
如果使用SSM框架结合Maven的项目构建工具,要配置一个编码过滤器的.统一使用UTF-8的国际编码代码如下:
<!--设置编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
至于GET的请求就使用UTF-8编码就可以了.
但是这只是可以解决POST的请求中文的编码的,GET请求中文的时候会依然乱码的。遇到问题总是要解决的嘛,来回看get的乱码.
response.setContentType("text/html;charset=UTF-8");是控制浏览器的行为,就是要浏览器使用UTF-8进行编码.
response.setCharacterEncoding("UTF-8");这个是用于response.getWriter()输出字符流的乱码问题的,将responses中的对象数据 进行以UTF-8解码后发向浏览器.
通过<meta http-equiv=“content-type" content="text/html"/>等价于response.setContentType("text/html").
不使用编码过滤器的时候,在使用JSP/Servlet的时候.如何处理GET和POST的中文乱码问题:
Get中文请求的乱码解决:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//将get传过来的参数重新编码
String username=new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
//发送的内容指定编码的格式
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(username);
}
Post中文请求的乱码解决:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username=request.getParameter("username");
response.getWriter().write(username);
}
还有一种解决方法:就是在tomcat的配置文件中指定编码格式的:
打开tomcat下的conf目录下的server.xml文件修改配置文件
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>.
三:Tomcat的结构分析--->
Tomcat服务器也好,Nginx官方说是可以支持50000的并发的轻量级的服务器也罢,都是基于模块的结构的.
Tomcat的总体结构如下图所示:核心组件是Connector和Container这两个组件
一个Container可以对应多个Connector的这样就组成了一个Service的,这样就可以提供服务了。
如图:
Tomcat的工作原理简单介绍:
一个Connecter将在某个指定的端口上侦听客户请求,接收浏览器的发过来的 tcp 连接请求,创建一个 Request 和 Response 对象分别用于和请求端交换数据,然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理Engine(Container中的一部分),Tomcat中有两个经典的Connector,一个直接侦听来自Browser的HTTP请求,另外一个来自其他的WebServer请求。Cotote HTTP/1.1 Connector在端口8080处侦听来自客户Browser的HTTP请求,Coyote JK2 Connector在端口8009处侦听其他Web Server的Servlet/JSP请求。 Connector 最重要的功能就是接收连接请求然后分配线程让 Container 来处理这个请求,所以这必然是多线程的,多线程的处理是 Connector 设计的核心。
Container的体系结构是典型使用了责任链的模式
Container是容器的父接口,该容器的设计用的是典型的责任链的设计模式,它由四个自容器组件构成,分别是Engine、Host、Context、Wrapper。这四个组件是负责关系,存在包含关系。通常一个Servlet class对应一个Wrapper,如果有多个Servlet定义多个Wrapper,如果有多个Wrapper就要定义一个更高的Container,如Context。
Context 还可以定义在父容器 Host 中,Host 不是必须的,但是要运行 war 程序,就必须要 Host,因为 war 中必有 web.xml 文件,这个文件的解析就需要 Host 了,如果要有多个 Host 就要定义一个 top 容器 Engine 了。而 Engine 没有父容器了,一个 Engine 代表一个完整的 Servlet 引擎。
Engine 容器比较简单,它只定义了一些基本的关联关系
Host 是 Engine 的字容器,一个 Host 在 Engine 中代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分它们。它的子容器通常是 Context,它除了关联子容器外,还有就是保存一个主机应该有的信息。
Context 代表 Servlet 的 Context,它具备了 Servlet 运行的基本环境,理论上只要有 Context 就能运行 Servlet 了。简单的 Tomcat 可以没有 Engine 和 Host。Context 最重要的功能就是管理它里面的 Servlet 实例,Servlet 实例在 Context 中是以 Wrapper 出现的,还有一点就是 Context 如何才能找到正确的 Servlet 来执行它呢? Tomcat5 以前是通过一个 Mapper 类来管理的,Tomcat5 以后这个功能被移到了 request 中,在前面的时序图中就可以发现获取子容器都是通过 request 来分配的。
Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器,它没有子容器了,所以调用它的 addChild 将会报错。
Wrapper 的实现类是 StandardWrapper,StandardWrapper 还实现了拥有一个 Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 将直接和 Servlet 的各种信息打交道
下面从server.xml的结构来看tomcat
<server>
<service>
<connector /> 简单组件,不需要封装
<engine>
<host>
<context>
</context>
</host>
<host>
</host>
</engine>
</service>
</server>
host虚拟主机。
四:Tomcat的工作分析--->
Tomcat Server处理一个HTTP请求的过程(没有改端口的)
将WAR包放到webapps的目录下Tomcat启动会自动解压的,Linux下使用的比较多的.将项目部署至Linux上访问.
案例url: http://localhost:8080/test/index.jsp
1、用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
2、Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。
5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。
6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。
7、Context把执行完之后的HttpServletResponse对象返回给Host。
8、Host把HttpServletResponse对象返回给Engine。
9、Engine把HttpServletResponse对象返回Connector。
10、Connector把HttpServletResponse对象返回给客户Browser。
至此十步完成了一个请求的发送到收到响应.
五:Tomcat的热部署--->
5.1: Tomcat的热部署的定义:
Tomcat的热部署就是在修改项目的BUG的时候修改JSP和JAVA的代码的时候,在不重启WEB服务器的时候让修改的内容生效,但如果修改的是框架的配置文件 时就不生效了.
1、直接把项目web文件夹放在webapps里。
2、在tomcat\conf\server.xml中的<host></host>内部添加<context/>标签:
<Context debug="0" docBase="D:\demo1\web" path="/demo1" privileged="true" reloadable="true"/>
docBase:项目路径,可以使用绝对路径或相对路径,相对路径是相对于webapps
path:访问项目的路径,如:http://127.0.0.1:8080/demo1
reloadable:是否自动加载新增或改变的class文件.
debug属性与这个Engine关联的Logger记录的调试信息的详细程度。数字越大,输出越详细。如果没有指定,缺省为0。 也就是程序异常时写入日志文件里的详细程度。
六:Tomcat的配置虚拟目录
6.1:介绍配置虚拟主机的两种方式:在做文件图片上传的demo的时候就会用到这个虚拟目录,指定物理路径,图片就会上传至那个目录下的,数据库里保存图片的路径,在开发头像显示的时候就可以用虚拟目录显示上传 的头像图片的.
6.1.1:在Tomcat的目录下server.xml做如下的配置,那个path就是虚拟的
<Context docBase="C:\apache-tomcat-7.0.77\webapps\SSM-demo" path="/SSM-demo" reloadable="true" source="org.eclipse.jst.jee.server:SSM-demo"/><Context docBase="D:\UpLoad" path="/pic" reloadable="true"/>
6.2:图形化界面配置:
七:Tomcat的CATALINA_HOME和CATALINA_BASE的区别:
你需要在一台机器上面部署多个Tomcat实例,但是你又不想创建多个Tomcat的副本,换句话说就是让这些Tomcat副本拥有自己的工作目录但是共享Tomcat的代码。
关于CATALINA_HOME和CATALINA_BASE
官方文档上面是这样解释的:
- Throughout the docs, you‘ll notice there are numerous references to $CATALINA_HOME. This represents the root of your Tomcat installation. When we say, "This information can be found in your $CATALINA_HOME/README.txt file" we mean to look at the README.txt file at the root of your Tomcat install. Optionally, Tomcat may be configured for multiple instances by defining $CATALINA_BASE for each instance. If multiple instances are not configured, $CATALINA_BASE is the same as $CATALINA_HOME.
翻译过来就是CATALINA_HOME是Tomcat的安装目录,CATALINA_BASE是Tomcat的工作目录.启动Tomcat会发现这个的.
八:Tomcat的双开问题:
解压两个Tomcat的,修改相应的端口的.分别启动,可以修改index.html那个首页便于区别的.
最后:将这些常见常用的归纳了一下:有些地方是学习知名博主的总结分享,一部分是自己学习过程中的一些总结的。这只是抛砖引玉只用的.鲜为人知的技术点还有很多的,一起分享一起快速的进步吧.