Я использую Jaxb2Marshaller для маршалинга Java-бинов с помощью аннотации spring @ResponseBody. Маршалинг JSON работал нормально. Но для xml я постоянно получал ответ HTTP 406. Небольшое копание в классе Jaxb2Marshaller показывает, что он проверяет @XmlRootElement для ограниченных классов (см. Фрагмент ниже).
При генерации java-кода из xsd мое pojo не содержит @XmlRootElement, и надлежащий преобразователь сообщений не был идентифицирован AnnotationMethodHandlerAdapter и, наконец, привел к 406.
Вместо автоматической генерации java-кода из xsd я создал свой собственный класс pojo и использовал @XmlRootElement. Тогда маршалинг работает нормально.
Я хочу понять, почему так важна проверка @XmlRootElement на наличие ограниченных классов. Или любой способ указать элемент как @XmlRootElement в xsd.
Фрагмент кода из Jaxb2Marshaller:
public boolean supports(Class clazz) {
return supportsInternal(clazz, true);
}
private boolean supportsInternal(Class<?> clazz, boolean checkForXmlRootElement) {
if (checkForXmlRootElement && clazz.getAnnotation(XmlRootElement.class) == null) {
return false;
}
if (clazz.getAnnotation(XmlType.class) == null) {
return false;
}
if (StringUtils.hasLength(getContextPath())) {
String className = ClassUtils.getQualifiedName(clazz);
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex == -1) {
return false;
}
String packageName = className.substring(0, lastDotIndex);
String[] contextPaths = StringUtils.tokenizeToStringArray(getContextPath(), ":");
for (String contextPath : contextPaths) {
if (contextPath.equals(packageName)) {
return true;
}
}
return false;
}
else if (!ObjectUtils.isEmpty(classesToBeBound)) {
return Arrays.asList(classesToBeBound).contains(clazz);
}
return false;
}
Изменить: Ответ Блэза помог мне решить проблему @XmlRootElement. Но все же, если у кого-то есть информация о том, почему требуется проверка XmlRootElement, будет хорошей информацией.