You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JAXB读取XML文件时出现Servlet实例化HTTP 500错误求助

问题描述

使用JAXB创建XML文件后,在Servlet中读取该文件时报HTTP 500错误,错误提示为Error instantiating servlet class(Servlet类实例化错误),调试后无法定位问题,需要排查XML读取逻辑及相关配置问题。

报错截图

error1
error2

1. Servlet代码

import java.io.*;
import java.util.List;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.xml.sax.SAXParseException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

@WebServlet
public class HelloServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws 
ServletException,IOException {
    try {
        PrintWriter out = response.getWriter();
        if(request.getParameter("name").equals("lol")){
            out.println("servlet working");
        }
        File file = new File("mvs.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Movie.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Movie m= (Movie) jaxbUnmarshaller.unmarshal(file);
        System.out.println(m.getFilm());
        out.println("Movies : ");
        List<movieINFO> list=m.getFilm();
        for(movieINFO mINFO:list)
            out.println(mINFO.getId()+" "+mINFO.getMovieName()+"  "
                    +mINFO.getDirector()+" "+mINFO.getReleaseDate()
                    +" "+mINFO.getTrailer());

    } catch (JAXBException e) {
        e.printStackTrace();
    }
}
}

2. web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee 
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
     version="5.0">
<servlet>
    <servlet-name>getMovie</servlet-name>
    <servlet-class>com.example.q1.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getMovie</servlet-name>
    <url-pattern>/movieName</url-pattern>
</servlet-mapping>
</web-app>

3. index.jsp代码

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Movie List</title>
</head>
<body>
<form action="movieName" method="post">
<h1>Movie List</h1>
<input placeholder="movie name" type="text" name="name">
<input type="submit" value="Submit">
</form>
</body>
</html> 

4. 待读取XML文件内容

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<film id="10">
    <director>Matthias Schweighöfer</director>
    <genre>Comedy/Action</genre>
    <movieName>Army of Thieves</movieName>
    <releaseDate>29/10/2021</releaseDate>
    <trailer>https://www.youtube.com/watch?v=Ith2WetKXlg</trailer>
</film>
<film id="11">
    <director> Denis Villeneuve</director>
    <genre>Sci-Fi/Adventure</genre>
    <movieName>Dune</movieName>
    <releaseDate>16/09/2021</releaseDate>
    <trailer>https://www.youtube.com/watch?v=n9xhJrPXop4</trailer>
</film>

问题排查与修复方案

1. 修复Servlet实例化失败问题

  • 你同时使用了@WebServlet注解和web.xml配置Servlet,二者冲突是实例化失败的核心原因,二选一即可:要么删除类上的@WebServlet注解,保留web.xml配置;要么删除web.xml里的servlet和servlet-mapping配置,给@WebServlet加上urlPatterns属性:@WebServlet("/movieName")
  • 核对HelloServlet的包路径是否和web.xml里配置的com.example.q1.HelloServlet完全一致,包名拼写错误也会导致类找不到,实例化失败。
  • 检查依赖兼容性:你用的是Jakarta EE 9+的Servlet包(jakarta.servlet开头),如果使用低版本JAXB(javax.xml.bind开头)会出现类加载冲突,替换为Jakarta兼容的JAXB实现即可,Maven项目参考依赖如下:
<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>3.0.1</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>3.0.1</version>
    <scope>runtime</scope>
</dependency>

2. 修复XML读取逻辑问题

  • 原代码用相对路径new File("mvs.xml")读取文件,Servlet运行时的工作目录是应用服务器的启动目录,不是项目资源目录,必然找不到文件。正确做法是把mvs.xml放到项目的WEB-INF/classes目录下,用ServletContext读取资源:
// 替换原File文件读取逻辑
InputStream is = getServletContext().getResourceAsStream("/mvs.xml");
Movie m= (Movie) jaxbUnmarshaller.unmarshal(is);
  • 补全XML文件的根节点闭合标签</movie>,否则XML格式错误会直接导致反序列化失败。
  • 检查Movie、movieINFO实体类的JAXB注解配置:Movie类要加@XmlRootElement(name = "movie"),存储film集合的字段要加@XmlElement(name = "film"),实体属性名要和XML节点名对应,否则反序列化会报错。
  • 对请求参数做空判断,避免用户未输入内容直接提交触发空指针异常:
String name = request.getParameter("name");
if("lol".equals(name)){
    out.println("servlet working");
}

内容的提问来源于stack exchange,提问作者Alex Alecco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:45:04