javax.xml.bind.JAXBException: class java.util.ArrayList 其任何超 class 在此上下文中都不为人所知
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context
我正在编写一个 MVC Java 程序,使用 JAXB 生成 XML 并发送到显示器 jsp。
代码运行并且 XML 在浏览器中正确显示,但我仍然在 IDE 控制台中收到 JAXBException。
我已经参考了关于该主题的几页 here and here。我已经按照建议添加了 JAXB 注释,但错误并没有消失。
有人能帮忙吗?
Web Servlet
@WebServlet(name = "GetAllFilms", value = "/GetAllFilms")
public class GetAllFilms extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
String jspDisplayString = "";
String dataFormat = request.getParameter("format");
if (dataFormat == null) dataFormat = "json";
FilmDAO filmDAO = new FilmDAO();
ArrayList<Film> allFilms = filmDAO.getAllFilms();
request.setAttribute("films", allFilms);
String viewJspFilePath = "";
if (dataFormat.equals("json")) {
response.setContentType("application/json");
viewJspFilePath = "/WEB-INF/results/films-json.jsp";
jspDisplayString = jsonGenerator(allFilms);
} else if (dataFormat.equals("xml")) {
response.setContentType("text/xml");
viewJspFilePath = "/WEB-INF/results/films-xml.jsp";
try {
jspDisplayString = xmlGenerator(allFilms);
} catch (JAXBException e) {
e.printStackTrace();
}
} else {
response.setContentType("text/plain");
viewJspFilePath = "/WEB-INF/results/films-string.jsp";
jspDisplayString = stringGenerator(allFilms);
}
RequestDispatcher dispatcher =
request.getRequestDispatcher(viewJspFilePath);
dispatcher.include(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
private String xmlGenerator(ArrayList<Film> allFilms)
throws JAXBException, FileNotFoundException {
FilmList filmList = new FilmList();
filmList.setFilmList(allFilms);
JAXBContext jaxbContext = JAXBContext.newInstance(FilmList.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(allFilms, stringWriter);
return stringWriter.toString();
}
}
电影模型Class(带有 JAXB 注释)
package model_beans;
@XmlRootElement(name = "film")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "id", "title", "year", "director", "stars", "review" })
public class Film {
public Film() {
}
public Film(int id, String title, int year, String director, String stars,
String review) {
super();
this.id = id;
this.title = title;
this.year = year;
this.director = director;
this.stars = stars;
this.review = review;
}
int id;
String title;
int year;
String director;
String stars;
String review;
*getters / setters excluded for ease of reading*
@Override
public String toString() {
return "Film [id=" + id + ", title=" + title + ", year=" + year
+ ", director=" + director + ", stars=" + stars + ", review="
+ review + "]";
}
}
FilmList 模型Class(带有 JAXB 注释)
package model_beans;
@XmlRootElement(namespace = "model_beans")
@XmlAccessorType(XmlAccessType.FIELD)
public class FilmList {
@XmlElementWrapper(name = "filmList")
@XmlElement(name = "film")
private ArrayList<Film> filmList;
public ArrayList<Film> getFilmList() {
return filmList;
}
public void setFilmList(ArrayList<Film> filmList) {
this.filmList = filmList;
}
}
JSP Xml 数据格式
<?xml version="1.0" encoding="UTF-8"?>
<%--@elvariable id="films" type="model_beans.Film"--%>
<%@taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core"%>
<films>
<headings>
<heading>Film ID</heading>
<heading>Title</heading>
<heading>Year</heading>
<heading>Director</heading>
<heading>Stars</heading>
<heading>Review</heading>
</headings>
<c:forEach items="${films}" var="f">
<film>
<id>${f.id}</id>
<title>${f.title}</title>
<year>${f.year}</year>
<director>${f.director}</director>
<stars>${f.stars}</stars>
<review>${f.review}</review>
</film>
</c:forEach>
</films>
堆栈跟踪
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:567)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:467)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:116)
at controller_servlets.GetAllFilms.xmlGenerator(GetAllFilms.java:125)
at controller_servlets.GetAllFilms.doGet(GetAllFilms.java:68)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
修改FilmList
class如下,
- 将
@XmlRootElement
注释添加到 class
- 从 class
中删除 @XmlElementWrapper
注释
FilmList.java
@XmlRootElement(name="filmList")
public class FilmList {
private ArrayList<Film> listFilm;
@XmlElement(name = "film")
public ArrayList<Film> getFilmList() {
return listFilm;
}
public void setFilmList(ArrayList<Film> listFilm) {
this.listFilm = listFilm;
}
}
Film.java
@XmlRootElement(name = "film")
@XmlType(propOrder = { "id", "title", "year", "director", "stars", "review" })
public class Film {
public Film() {
}
public Film(int id, String title, int year, String director, String stars,
String review) {
super();
this.id = id;
this.title = title;
this.year = year;
this.director = director;
this.stars = stars;
this.review = review;
}
int id;
String title;
int year;
String director;
String stars;
String review;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getStars() {
return stars;
}
public void setStars(String stars) {
this.stars = stars;
}
public String getReview() {
return review;
}
public void setReview(String review) {
this.review = review;
}
@Override
public String toString() {
return "Film [id=" + id + ", title=" + title + ", year=" + year
+ ", director=" + director + ", stars=" + stars + ", review="
+ review + "]";
}
}
Marshaller.java
public class Marshaller {
public static void main(String[] args) {
ArrayList<Film> listFilm = new ArrayList<>();
StringWriter stringWriter = new StringWriter();
FilmList filmList = new FilmList();
Film film = new Film();
film.setDirector("a");
film.setId(1);
film.setReview("b");
film.setStars("c");
film.setTitle("e");
film.setYear(2020);
listFilm.add(film);
filmList.setFilmList(listFilm);
try {
JAXBContext jaxbContext = JAXBContext.newInstance(FilmList.class);
javax.xml.bind.Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(filmList, stringWriter);
} catch (JAXBException e) {
e.printStackTrace();
}
System.out.println(stringWriter);
}
}
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<filmList>
<film>
<id>1</id>
<title>e</title>
<year>2020</year>
<director>a</director>
<stars>c</stars>
<review>b</review>
</film>
</filmList>
已编辑
出现以下错误的原因是 @XmlRootElement
和 ArrayList<Film>
使用了相同的名称 (filmList
)。因此,请将 ArrayList<Film>
的名称更改为 listFilm
注意。请设置@XmlElement
注解获取方法
最后编辑
在上面的 servlet 中,您尝试在 xmlGenerator 方法中编组 java 集合(电影列表 (allFilms)
)。
marshaller.marshal(allFilms, stringWriter);
但无法编组集合,并且 java 集合 class 没有 JAXB 注释。
在您的例子中,创建了 FilmList
对象,但它不用于编组。我认为这是你的错误。请编组 filmList
如下
marshaller.marshal(filmList, stringWriter);
我正在编写一个 MVC Java 程序,使用 JAXB 生成 XML 并发送到显示器 jsp。 代码运行并且 XML 在浏览器中正确显示,但我仍然在 IDE 控制台中收到 JAXBException。
我已经参考了关于该主题的几页 here and here。我已经按照建议添加了 JAXB 注释,但错误并没有消失。
有人能帮忙吗?
Web Servlet
@WebServlet(name = "GetAllFilms", value = "/GetAllFilms")
public class GetAllFilms extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
String jspDisplayString = "";
String dataFormat = request.getParameter("format");
if (dataFormat == null) dataFormat = "json";
FilmDAO filmDAO = new FilmDAO();
ArrayList<Film> allFilms = filmDAO.getAllFilms();
request.setAttribute("films", allFilms);
String viewJspFilePath = "";
if (dataFormat.equals("json")) {
response.setContentType("application/json");
viewJspFilePath = "/WEB-INF/results/films-json.jsp";
jspDisplayString = jsonGenerator(allFilms);
} else if (dataFormat.equals("xml")) {
response.setContentType("text/xml");
viewJspFilePath = "/WEB-INF/results/films-xml.jsp";
try {
jspDisplayString = xmlGenerator(allFilms);
} catch (JAXBException e) {
e.printStackTrace();
}
} else {
response.setContentType("text/plain");
viewJspFilePath = "/WEB-INF/results/films-string.jsp";
jspDisplayString = stringGenerator(allFilms);
}
RequestDispatcher dispatcher =
request.getRequestDispatcher(viewJspFilePath);
dispatcher.include(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
private String xmlGenerator(ArrayList<Film> allFilms)
throws JAXBException, FileNotFoundException {
FilmList filmList = new FilmList();
filmList.setFilmList(allFilms);
JAXBContext jaxbContext = JAXBContext.newInstance(FilmList.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(allFilms, stringWriter);
return stringWriter.toString();
}
}
电影模型Class(带有 JAXB 注释)
package model_beans;
@XmlRootElement(name = "film")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "id", "title", "year", "director", "stars", "review" })
public class Film {
public Film() {
}
public Film(int id, String title, int year, String director, String stars,
String review) {
super();
this.id = id;
this.title = title;
this.year = year;
this.director = director;
this.stars = stars;
this.review = review;
}
int id;
String title;
int year;
String director;
String stars;
String review;
*getters / setters excluded for ease of reading*
@Override
public String toString() {
return "Film [id=" + id + ", title=" + title + ", year=" + year
+ ", director=" + director + ", stars=" + stars + ", review="
+ review + "]";
}
}
FilmList 模型Class(带有 JAXB 注释)
package model_beans;
@XmlRootElement(namespace = "model_beans")
@XmlAccessorType(XmlAccessType.FIELD)
public class FilmList {
@XmlElementWrapper(name = "filmList")
@XmlElement(name = "film")
private ArrayList<Film> filmList;
public ArrayList<Film> getFilmList() {
return filmList;
}
public void setFilmList(ArrayList<Film> filmList) {
this.filmList = filmList;
}
}
JSP Xml 数据格式
<?xml version="1.0" encoding="UTF-8"?>
<%--@elvariable id="films" type="model_beans.Film"--%>
<%@taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core"%>
<films>
<headings>
<heading>Film ID</heading>
<heading>Title</heading>
<heading>Year</heading>
<heading>Director</heading>
<heading>Stars</heading>
<heading>Review</heading>
</headings>
<c:forEach items="${films}" var="f">
<film>
<id>${f.id}</id>
<title>${f.title}</title>
<year>${f.year}</year>
<director>${f.director}</director>
<stars>${f.stars}</stars>
<review>${f.review}</review>
</film>
</c:forEach>
</films>
堆栈跟踪
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:567)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:467)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:116)
at controller_servlets.GetAllFilms.xmlGenerator(GetAllFilms.java:125)
at controller_servlets.GetAllFilms.doGet(GetAllFilms.java:68)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
修改FilmList
class如下,
- 将
@XmlRootElement
注释添加到 class - 从 class 中删除
@XmlElementWrapper
注释
FilmList.java
@XmlRootElement(name="filmList")
public class FilmList {
private ArrayList<Film> listFilm;
@XmlElement(name = "film")
public ArrayList<Film> getFilmList() {
return listFilm;
}
public void setFilmList(ArrayList<Film> listFilm) {
this.listFilm = listFilm;
}
}
Film.java
@XmlRootElement(name = "film")
@XmlType(propOrder = { "id", "title", "year", "director", "stars", "review" })
public class Film {
public Film() {
}
public Film(int id, String title, int year, String director, String stars,
String review) {
super();
this.id = id;
this.title = title;
this.year = year;
this.director = director;
this.stars = stars;
this.review = review;
}
int id;
String title;
int year;
String director;
String stars;
String review;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getStars() {
return stars;
}
public void setStars(String stars) {
this.stars = stars;
}
public String getReview() {
return review;
}
public void setReview(String review) {
this.review = review;
}
@Override
public String toString() {
return "Film [id=" + id + ", title=" + title + ", year=" + year
+ ", director=" + director + ", stars=" + stars + ", review="
+ review + "]";
}
}
Marshaller.java
public class Marshaller {
public static void main(String[] args) {
ArrayList<Film> listFilm = new ArrayList<>();
StringWriter stringWriter = new StringWriter();
FilmList filmList = new FilmList();
Film film = new Film();
film.setDirector("a");
film.setId(1);
film.setReview("b");
film.setStars("c");
film.setTitle("e");
film.setYear(2020);
listFilm.add(film);
filmList.setFilmList(listFilm);
try {
JAXBContext jaxbContext = JAXBContext.newInstance(FilmList.class);
javax.xml.bind.Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(filmList, stringWriter);
} catch (JAXBException e) {
e.printStackTrace();
}
System.out.println(stringWriter);
}
}
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<filmList>
<film>
<id>1</id>
<title>e</title>
<year>2020</year>
<director>a</director>
<stars>c</stars>
<review>b</review>
</film>
</filmList>
已编辑
出现以下错误的原因是 @XmlRootElement
和 ArrayList<Film>
使用了相同的名称 (filmList
)。因此,请将 ArrayList<Film>
的名称更改为 listFilm
注意。请设置@XmlElement
注解获取方法
最后编辑
在上面的 servlet 中,您尝试在 xmlGenerator 方法中编组 java 集合(电影列表 (allFilms)
)。
marshaller.marshal(allFilms, stringWriter);
但无法编组集合,并且 java 集合 class 没有 JAXB 注释。
在您的例子中,创建了 FilmList
对象,但它不用于编组。我认为这是你的错误。请编组 filmList
如下
marshaller.marshal(filmList, stringWriter);