前言

  • 我们在使用Servlet创建JavaWeb项目时,想要绑定url路径和Servlet的映射关系,需要在web.xml中配置映射关系。
  • Servlet从2.5版本开始支持注解。具体来说,Servlet 2.5引入了注解配置方式,使得Servlet应用程序的配置更加简单、灵活。在此之前,Servlet的配置主要通过web.xml文件来完成。而从Servlet 2.5开始,开发人员可以通过注解(如@WebServlet)直接在Servlet类上进行配置,省去了编辑web.xml文件的繁琐步骤。

 此时容易出现一个常见的问题,接下来实例演示:

没有使用注解的Servlet配置

例:

一个简单的javaWeb项目的结构如下:此时只包含一个Servlet类

 只使用web.xml进行Servlet配置的源码配置文件如下:

Servle类:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ServletTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应类型和响应字符集,防止中文乱码
        response.setContentType("text/html;charset=UTF-8");
        //获取响应输出流
        PrintWriter out = response.getWriter();
        //在页面打印HTML标签(会解析成对应的效果)
        out.println("<html>");
        out.println("<head><title>Servlet</title></head>");
        out.println("<body>");
        out.println("你好,欢迎来到Servlet世界");
        out.println("</body>");
        out.println("</html>");
        //使用完毕,关闭流资源
        out.close();

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp); //目的是为了保证前端传入的get和post请求都能接收处理
    }
}

web.xml配置文件: 

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>httpServletTest</servlet-name>
    <servlet-class>ServletTest</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>httpServletTest</servlet-name>
    <url-pattern>/demo1</url-pattern>
  </servlet-mapping>
</web-app>

使用注解的Servlet配置

在Servlet类上方加上注解@WebServlet

Servlet类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/demo1")
public class ServletTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应类型和响应字符集,防止中文乱码
        response.setContentType("text/html;charset=UTF-8");
        //获取响应输出流
        PrintWriter out = response.getWriter();
        //在页面打印HTML标签(会解析成对应的效果)
        out.println("<html>");
        out.println("<head><title>Servlet</title></head>");
        out.println("<body>");
        out.println("你好,欢迎来到Servlet世界");
        out.println("</body>");
        out.println("</html>");
        //使用完毕,关闭流资源
        out.close();

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp); //目的是为了保证前端传入的get和post请求都能接收处理
    }
}

web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<!--  <display-name>Archetype Created Web Application</display-name>-->
<!--  <servlet>-->
<!--    <servlet-name>httpServletTest</servlet-name>-->
<!--    <servlet-class>ServletTest</servlet-class>-->
<!--  </servlet>-->
<!--  <servlet-mapping>-->
<!--    <servlet-name>httpServletTest</servlet-name>-->
<!--    <url-pattern>/demo1</url-pattern>-->
<!--  </servlet-mapping>-->
</web-app>

出现问题

此时可能会出现以下问题:

出现原因:web.xml配置文件的头部必须是2.5以上,否则是不支持Servlet注解的,因此找不到对应路径 。

注意: 出现这个问题,本质上是配置文件版本过低导致的,但是这种情况在jetty服务器中一定可以看的到,如果使用的是tomcat服务器,即使你的web.xml头部不是2.5版本以上的,依旧可以访问对应的路径(web.xml的内容可以没有,但结构一定要保留,否则会直接报错)

问题解决

修改方法:,将web.xml的配置版本声明为高版本:注意要添加@WebServlet注解

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee   
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 配置内容 -->
</web-app>

各版本的web.xml头部

         Servlet的web.xml配置文件是Java Web应用的重要组成部分,它用于定义Web应用的配置信息,如Servlet、Filter、Listener等的声明和映射。随着Servlet规范的不断发展,web.xml的配置头部信息也有所变化。以下是Servlet各版本的web.xml配置头部示例:

Servlet 2.3

  • Servlet 2.3版本使用的是DTD(Document Type Definition)来声明文档类型,配置头部如下所示:
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
"http://java.sun.com/dtd/web-app_2_3.dtd">  
<web-app>  
    <!-- 配置内容 -->  
</web-app>

Servlet 2.4

  • Servlet 2.4版本开始使用XML Schema来定义XML文件的格式,配置头部如下所示:
<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"  
         version="2.4">  
    <!-- 配置内容 -->  
</web-app>

Servlet 2.5

  • Servlet 2.5版本的配置头部与2.4类似,但命名空间和schemaLocation略有不同,以反映Java EE 5的变更:
<?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_2_5.xsd"  
         version="2.5">  
    <!-- 配置内容 -->  
</web-app>

Servlet 3.0

  • Servlet 3.0版本继续沿用XML Schema,但命名空间和schemaLocation更新为与Java EE 6相匹配:
<?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">  
    <!-- 配置内容 -->  
</web-app>

Servlet 3.1

  • Servlet 3.1版本的配置头部与3.0类似,但版本号更新为3.1,并且命名空间更新为与Java EE 7相匹配(注意域名从java.sun.com更改为xmlns.jcp.org):
<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee   
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"  
         version="3.1">  
    <!-- 配置内容 -->  
</web-app>

Servlet 4.0

  • Servlet 4.0版本的配置头部与之前的版本类似,但版本号更新为4.0,并且继续沿用Java EE的命名空间和schemaLocation:
<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee   
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"  
         version="4.0">  
    <!-- 配置内容 -->  
</web-app>

请注意,随着Java EE和Jakarta EE的演变,未来版本的Servlet可能会使用不同的命名空间和schemaLocation。上述信息是基于当前可用的最新规范和文档。

 总结

使用注解时,尤其需要注意,支持使用注解的版本是哪个,如果当前版本不支持,极大可能导致我们使用的注解失效。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐