类及其任何超类对此上下文都是已知的



我试图理解我遇到的这个特殊问题。在这里使用Spring OXM来实现Soap WS Consumer。

我只是附上相关信息来解释这个问题。

登录配置,

@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)中失败。

这是由于两者,

@Autowired
private UserClient iamUserClient;
@Autowired
private LoginClient iamLoginClient;

彼此冲突。拥有单独的jaxb2Marshaller并将其传递给WebServiceTemplate解决了问题。

因此登录配置更新为,

@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);
}
}

相关内容

  • 没有找到相关文章

最新更新