2015-09-02 52 views
0

我想將用戶記錄緩存在XML文件中。爲此,我編寫了以下測試應用程序。針對java接口的JAXB IllegalAnnotationsException

當我運行這個我得到一個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; 
    } 
} 

錯誤說,該方法getAuthorities()中用戶類返回的接口,並且JAXB不能處理接口。

那麼這個問題的解決方法是什麼?

在此先感謝。

回答

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; 
    } 
+0

但我需要堅持的角色也是如此。所以爲此我可以爲UserRole創建一個類並保持正確? – Leejoy

+0

在我的用戶中,我有eRole,可以有很多rigths。角色作爲私人角色角色持續存在;擁有自己的getter和setter。 getAuthorities在getRole()和getRights()上實現委託,因爲我已經更新了我的答案。所以getAutorities()可以保持爲一個瞬態方法,僅用於實現SpringSecurity的UserDetails接口。 –

+0

謝謝,它工作:) – Leejoy