我试图理解我遇到的这个特殊问题。在这里使用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
)失败。
答案 0 :(得分:2)
这是因为两者都是,
@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;
}
}
答案 1 :(得分:0)
此配置在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);
}
}