新建web项目
eclipse新建一个Dynamic Web Project,在WebContent下新建一个html文件,取名index.html,在body标签里面输入“Hello,World!“,项目右键=》Run As=》Run on Server选择对应的Tomcat,就可以在浏览器访问这个html了。
直接访问http://localhost:8080/HelloWeb/就可以请求到index.html,而不需要http://localhost:8080/HelloWeb/index.html,这是因为index.html是Tomcat默认的欢迎页面。
在$TOMCAT_HOME/conf/web.xml中可以修改欢迎页的配置,比如改成默认访问home.html。在这个文件里面还配置具体请求到对应处理类的映射关系等。这是Tomcat的全局配置,对这个Tomcat下的所有应用起作用,可以把这个web.xml复制到项目的WEB-INF目录下,对其进行改写,删掉默认的配置,根据需要覆盖Tomcat的全局配置,只对本项目起作用。
web.xml
删掉web.xml里面的注释,来看下这里面配置了哪些东西。
<?xml version="1.0" encoding="utf-8"?> <!-- 声明这个xml文档的解析编码 -->
<!-- xmlns声明一个默认的命名空间 -->
<!-- xmlns:xsi默认的xsd命名空间,xsd为xml的结构定义文件 -->
<!-- xsi:schemaLocation指明前面xsi的声明的xsd文件的位置,编辑器会根据这个文件校验这个xml文件的格式 -->
<!-- version版本号 -->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
这里声明了一个servlet对象,名称是default,类名是org.apache.catalina.servlets.DefaultServlet,并初始化参数debug值为0,listings值为false。load-on-startup 元素标记容器是否应该在web应用程序启动的时候就加载这个servlet, 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。
声明一个servlet的同时会声明一个servlet-mapping元素,url-pattern元素用来匹配请求路径,这里“/”指根路径,当访问根路径下的目录时会执行servlet-name声明的servlet,这里是default,即是上面声明的那个servlet。
另一个servlet-name为jsp的servlet声明功能类似。DefaultServlet是默认的资源处理类,JspServlet是默认的jsp文件的处理类。
Servlet对外访问的虚拟路径的匹配顺序大致如下:
- 含有全部或部分对外访问的具体路径配置,如/LoginServlet,/servlet/*(优先匹配更为具体的路径);
- /*的配置;
- 形如*.action这样后缀形式的配置,如index.jsp,login.action(即使是具体的路径,优先级也会低于1和2的配置);
- 其它配置无法匹配的时候,匹配/所配置的Servlet。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
设置session超时时间,单位是分钟,默认是30分钟。
<mime-mapping>
<extension>7z</extension>
<mime-type>application/x-7z-compressed</mime-type>
</mime-mapping>
有一堆mime-mapping,声明一些格式,比如7z,当服务器返回xxxx.7z文件的时候,声明返回的数据格式是application/x-7z-compressed,这样子浏览器就不会傻傻的打开这个文件了,而是弹出下载提示。
可以用mine-mapping配置返回的html的编码格式。 比如:
<mime-mapping>
<extension>html</extension>
<mime-type>text/html;charset=utf-8</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
欢迎文件列表,当访问根路径没有指明具体资源名字的时候(如http://localhost:8080/HelloWeb/),会从这个列表从上往下匹配,找到对应的文件就返回到浏览器。
Servlet版hello world
什么是http,http是一种网络协议,浏览器通过http请求具体的资源,服务器把资源封装成http格式的报文,返回给浏览器,浏览器就能识别具体的内容。相应的什么是servlet,servlet是javaweb的一种规范,Tomcat等javaweb服务器能够识别,并将请求转发给对对应的servlet对象去处理。
新建一个HelloworldServlet,并在WEB-INF下的web.xml里面配置映射关系。
package com.helloworld.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* servlet默认会执行service方法
* service方法根据请求的类型调用具体的方法,如调用post或者get方法
*
*/
public class HelloworldServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String message = "hello, world!";
resp.setContentType("text/html"); // 声明返回的数据类型是html
PrintWriter out = resp.getWriter(); // 获取response的writer对象
out.println("<h1>" + message + "</h1>"); // 向response写入字符
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doPost(req, resp);
}
}
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>helloworld</servlet-name>
<servlet-class>com.helloworld.servlet.HelloworldServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>helloworld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
启动项目,访问http://localhost:8080/HelloWeb/hello,即可看到打印出来的字符
对于动态页面,javaweb应用刚开始就是用Servlet这样子一行一行动态打印出来的,对于现在花里胡哨的页面,用这种方式生成,显然太过于垃圾,所以后来出现了JSP。
- 开始时JSP通过在html页面嵌套java代码,当服务器返回jsp页面的时候,服务器端会动态解析生成对应的Servlet,由Servlet打印出html返回给客户端。
- 再后来,MVC分层理念出现,JSP页面不提倡出现显式的java代码,取而代之的是各种表达式,如EL表达式,OGNL表达式,服务器解析jsp的时候会动态计算这些表达式的值,通过表达式来动态填充数据。这种方式是比较麻烦的,所以一般浏览器拿到页面后,还会根据需要发起ajax请求到后台拿数据。
- 再到现在流行前后端分离,前端代码彻底从后台分离,浏览器访问页面时首先向前端静态资源服务器发起请求,拿到静态的页面后,再发起ajax请求动态的从后台服务器拉取数据,拿到数据后用JavaScript组织页面。
JSP现在还是有很多项目在用,不过以后应该会被淘汰吧。
参考文章
详解 xml 文件头部的 xmlns:xsi:https://blog.csdn.net/lengxiao1993/article/details/77914155
web.xml中load-on-startup的作用:https://www.cnblogs.com/lemon-now/p/5542301.html
深入理解web.xml中配置/和/*的区别:https://blog.csdn.net/jinghuashuiyue2/article/details/78589655?locationNum=7&fps=1
web.xml配置中的mime-mapping:https://blog.csdn.net/xinyuan_java/article/details/52764576
Web容器中DefaultServlet详解:https://blog.csdn.net/qq_30920821/article/details/78328608