Класс, ни один из его суперкласса не известен в этом контексте

Я пытаюсь понять эту конкретную проблему, которую я имею. Использование Spring OXM здесь для реализации Soap WS Consumer.

Я только прилагаю соответствующую информацию, чтобы объяснить проблему.

LoginWsConfiguration,

@Configuration
public class LoginWsConfiguration {

    @Inject
    private OnboardingProperties onboardingProperties;

    @Bean
    Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller
            .setPackagesToScan("org.openiam.ws.login.api_3_2_6");
        try {
            jaxb2Marshaller.afterPropertiesSet();
        }
        catch (Exception ex) {
            throw new BeanCreationException(ex.getMessage(), ex);
        }
        return jaxb2Marshaller;
    }

    @Bean
    public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller jaxb2Marshaller) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        webServiceTemplate.setMarshaller(jaxb2Marshaller);
        webServiceTemplate.setUnmarshaller(jaxb2Marshaller);
        webServiceTemplate.setDefaultUri(onboardingProperties.getIAM().getEndpoint().getLogin());

        return webServiceTemplate;
    }

И клиент LoginClient реализован как,

@Component
public class LoginClient {

    private static final Logger log = LoggerFactory.getLogger(IAMLoginClient.class);

    @Autowired
    private LoginMapper loginMapper;

    @Inject
    private OnboardingProperties onboardingProperties;

    private WebServiceTemplate webServiceTemplate;

    @Autowired
    public LoginClient(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }

    public LoginClient() {
    }

    public Optional getLoginByUserId(final String userId) {
        ObjectFactory factory = new ObjectFactory();
        GetLoginByUser req = factory.createGetLoginByUser();
        req.setUserId(userId);
        GetLoginByUserResponse resp = (GetLoginByUserResponse)webServiceTemplate.marshalSendAndReceive(req);
        if (resp != null && resp.getReturn() != null && resp.getReturn().getStatus() == org.openiam.ws.login.api_3_2_6.ResponseStatus.SUCCESS) {
            List<Login> foundLogins = resp.getReturn().getPrincipalLists();
            Login foundLogin = foundLogins.stream()
                .filter(login -> login.getManagedSysId().equals(Constants.IAM_DEFAULT_MANAGED_SYS_ID))
                .findFirst()
                .orElse(null);
            return Optional.ofNullable((foundLogin != null) ? this.loginMapper.mapIAMLogin(foundLogin) : null);
        }
        return Optional.empty();
    }

Для полноты, GetLoginByUser,

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getLoginByUser", propOrder = {
    "userId"
})
@XmlRootElement(name = "getLoginByUser")
public class GetLoginByUser {

    protected String userId;

    /**
     * Gets the value of the userId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getUserId() {
        return userId;
    }

    /**
     * Sets the value of the userId property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setUserId(String value) {
        this.userId = value;
    }

}

GetLoginByUserResponse,

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getLoginByUserResponse", propOrder = {
    "_return"
})
@XmlRootElement(name = "getLoginByUserResponse")
public class GetLoginByUserResponse {

    @XmlElement(name = "return")
    protected LoginListResponse _return;

    /**
     * Gets the value of the return property.
     * 
     * @return
     *     possible object is
     *     {@link LoginListResponse }
     *     
     */
    public LoginListResponse getReturn() {
        return _return;
    }

    /**
     * Sets the value of the return property.
     * 
     * @param value
     *     allowed object is
     *     {@link LoginListResponse }
     *     
     */
    public void setReturn(LoginListResponse value) {
        this._return = value;
    }

}

Тем не менее, когда я пытаюсь,

@Autowired
private UserClient iamUserClient;

@Autowired
private LoginClient iamLoginClient;

Optional<IAMUser> userFromIAM = iamUserClient.getUserByPrincipal(lowercaseLogin);
IAMUser userIAM = userFromIAM.
        orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in IAM"));
    if (userIAM.getStatus() != IAMUserStatus.ACTIVE || userIAM.getAccountStatus() != null) {
        throw new UserNotActivatedException("User " + lowercaseLogin + " is not active");
    }
Optional<IAMLogin> loginFromIAM = iamLoginClient.getLoginByUserId(userIAM.getId());

Я получаю ошибку,

org.springframework.oxm.UncategorizedMappingException: Unknown JAXB exception; nested exception is javax.xml.bind.JAXBException: class org.openiam.ws.login.api_3_2_6.GetLoginByUser nor any of its super class is known to this context.
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:915)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:684)
    at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:81)
    at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:399)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:590)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
    at com.orchestral.dsm.onboarding.iam.ws.login.LoginClient.getLoginByUserId(LoginClient.java:77)
    at com.orchestral.dsm.onboarding.security.IAMUserDetailsService.loadUserByUsername(IAMUserDetailsService.java:45)

Из того, что я вижу, он не терпит неудачу при сортировке в getUserByPrincipal (UserClient) но терпит неудачу на getLoginByUserId (LoginClient).

1 ответ

Решение

Это было связано с тем, что оба,

@Autowired
private UserClient iamUserClient;

@Autowired
private LoginClient iamLoginClient;

были в конфликте друг с другом. Имея индивидуальный jaxb2Marshaller и передать это WebServiceTemplate исправил проблему.

Итак, LoginWsConfiguration обновлен до

@Configuration
public class LoginWsConfiguration {

    @Bean
    Jaxb2Marshaller jaxb2LoginMarshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setPackagesToScan("org.openiam.ws.login.api_3_2_6");
        return jaxb2Marshaller;
    }

    @Bean
    public LoginClient loginClient(Jaxb2Marshaller jaxb2LoginMarshaller) {
        LoginClient client = new LoginClient();
        client.setMarshaller(jaxb2LoginMarshaller);
        client.setUnmarshaller(jaxb2LoginMarshaller);
        client.setDefaultUri("uri");

        return client;
    }
}

Эта конфигурация работала для меня в Spring 4, и теперь в Spring 5 я вижу, что WebMvcConfigurerAdapter устарел, но он все еще работает:

@Configuration
@EnableWebMvc
@ComponentScan({})
public class WebConfig extends WebMvcConfigurerAdapter {

    public MappingJackson2HttpMessageConverter jacksonMessageConverter() {
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = new ObjectMapper(); 
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

        mapper.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false);
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

        messageConverter.setObjectMapper(mapper);
        return messageConverter;

    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
        converters.add(jacksonMessageConverter());
        super.configureMessageConverters(converters);
    }
}
Другие вопросы по тегам