我正在尝试将用户记录缓存在XML文件中。为此,我编写了以下测试应用程序。
当我运行此操作时,我收到IllegalAnnotationsException。
以下是错误详情:
Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
org.springframework.security.core.GrantedAuthority is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at org.springframework.security.core.GrantedAuthority
at public java.util.Set User.getAuthorities()
at User
at public java.util.List UserXMLRepository$UserDataTable.users
at UserXMLRepository$UserDataTable
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at UserXMLRepository.create(Test.java:64)
at Test.main(Test.java:35)
测试申请:
public class Test {
public static void main(String[] args) throws Exception {
UserXMLRepository.create();
}
}
final class UserXMLRepository {
public final static String rootDirectory = "E:/test";
public final static String xmlFile = rootDirectory + "/userDataTable.xml";
@XmlRootElement()
public static final class UserDataTable {
// XmLElementWrapper generates a wrapper element around XML representation
@XmlElementWrapper(name = "userList")
// XmlElement sets the name of the entities
@XmlElement(name = "user")
public List<User> users = new ArrayList<User>();
}
public static void create() throws JAXBException
{
File f = new File(rootDirectory);
if(!f.exists())
f.mkdirs();
File xml = new File(xmlFile);
if(!xml.exists())
{
JAXBContext context;
try {
context = JAXBContext.newInstance(UserDataTable.class);
Marshaller jaxbMarshaller = context.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(new UserDataTable(), xml);
} catch (JAXBException e) {
throw e;
}
}
}
public static String getXmlfile() {
return xmlFile;
}
}
class User implements UserDetails {
private static final long serialVersionUID = -4449202586601819593L;
private String username;
private String password;
private Set<GrantedAuthority> authorities;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled = true;
public User() {
}
public User(String username, String password,
Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
public User(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
this.username = username;
this.password=password;
this.accountNonExpired = accountNonExpired;
this.credentialsNonExpired = credentialsNonExpired;
this.accountNonLocked = accountNonLocked;
this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities==null ? new ArrayList<GrantedAuthority>() : authorities));
}
private static SortedSet<GrantedAuthority> sortAuthorities(Collection<? extends GrantedAuthority> authorities) {
Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection");
// Ensure array iteration order is predictable (as per UserDetails.getAuthorities() contract and SEC-717)
SortedSet<GrantedAuthority> sortedAuthorities =
new TreeSet<GrantedAuthority>(new AuthorityComparator());
for (GrantedAuthority grantedAuthority : authorities) {
Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements");
sortedAuthorities.add(grantedAuthority);
}
return sortedAuthorities;
}
private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
public int compare(GrantedAuthority g1, GrantedAuthority g2) {
if (g2.getAuthority() == null) {
return -1;
}
if (g1.getAuthority() == null) {
return 1;
}
return g1.getAuthority().compareTo(g2.getAuthority());
}
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Set<GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<GrantedAuthority> authorities) {
this.authorities = authorities;
}
public boolean isAccountNonExpired() {
return accountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
错误说User类中的方法getAuthorities()返回一个接口,而JAXB无法处理接口。
那么这个问题的解决方法是什么?
提前致谢。
答案 0 :(得分:0)
您是否尝试使用@XmlTransient在User类中注释getAuthorities()?
我实现了几乎相同的实现生成JSON的Rest服务:
@Override
@JsonIgnore //Tell Jackson to ignore this metod, you can use @XMLTransient
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
if (getRole() != null) {
for (Right right : getRole().getRights()) {
GrantedAuthority authority = new GrantedAuthority(right.getName());
authorities.add(authority);
}
}
return authorities;
}