Unable to load wsdl using GUI tool using spring boot - java

I am new to both SOAP & spring boot technologies.However i have created soap webservice using below reference link.
https://spring.io/guides/gs/producing-web-service/
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "REL-6-MM7-1-4")
#Primary
public DefaultWsdl11Definition defaultWsdl11Definition() {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("MMSPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4");
wsdl11Definition.setSchemaCollection(getXsdCollection());
return wsdl11Definition;
}
#Bean
public XsdSchemaCollection getXsdCollection() {
return new XsdSchemaCollection() {
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[]{new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd")), new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"))};
}
public XmlValidator createValidator() {
throw new UnsupportedOperationException();
}
};
}
Please find xsd posted.

This is the error that happen when you are not using the correct url into soap ui.
You need to search the right location of your XSD in the browser and make sure you can access to it.
Then you need to check the URL you are pasting into SOAP UI and see if the relative URLs actually are correct.
If they aren't, you have to use the correct location.
Edit :
In your case, I see the following code :
#Bean(name = "REL-6-MM7-1-4")
So I think that your ws is exposed at :
http://localhost:8080/ws/REL-6-MM7-1-4.wsdl
Edit 2 :
In your case, you also need to provide multiple xsd. You can do it by adding :
#Bean
public XsdSchemaCollection getXsdCollection() {
return new XsdSchemaCollection() {
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[]{new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd")), new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"))};
}
public XmlValidator createValidator() {
throw new UnsupportedOperationException();
}
};
}
and by using it at :
wsdl11Definition.setSchema(getXsdCollection());

Related

Exporting two services in Spring

I have a problem in Spring such that I get the next error when I try to export two services from server to client:
Caused by: org.springframework.remoting.RemoteLookupFailureException: Could not find RMI service [rmi://localhost:1099/ClientsService] in RMI registry; nested exception is java.rmi.NotBoundException: ClientsService
This is my Configuration in the server side:
#Configuration
public class ClientsServerConfig {
#Bean
RmiServiceExporter rmiServiceExporter() {
RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setServiceInterface(ClientService.class);
rmiServiceExporter.setService(clientService());
rmiServiceExporter.setServiceName("ClientsService");
return rmiServiceExporter;
}
#Bean
ClientService clientService() {
return new ClientsServiceImpl(clientRepository());
}
#Bean
RepositoryInterface<Long, Client> clientRepository() {
return new ClientDbRepository();
}
}
and
#Configuration
public class GunProviderServerConfig{
#Bean
RmiServiceExporter rmiServiceExporter() {
RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
rmiServiceExporter.setServiceInterface(GunProviderService.class);
rmiServiceExporter.setService(gunProviderService());
rmiServiceExporter.setServiceName("GunProviderService");
return rmiServiceExporter;
}
#Bean
GunProviderService gunProviderService() {
return new GunProviderServiceImpl(gunProviderRepository());
}
#Bean
RepositoryInterface<Long, GunProvider> gunProviderRepository() {
return new GunProviderDbRepository();
}
}
and this is the configuration in the client side:
#Configuration
public class ClientConfig {
#Bean
RmiProxyFactoryBean rmiProxyFactoryBean() {
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceUrl("rmi://localhost:1099/ClientsService");
rmiProxyFactoryBean.setServiceInterface(ClientService.class);
return rmiProxyFactoryBean;
}
#Bean
RmiProxyFactoryBean rmiProxyFactoryBean2() {
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceUrl("rmi://localhost:1099/GunProviderService");
rmiProxyFactoryBean.setServiceInterface(GunProviderService.class);
return rmiProxyFactoryBean;
}
And the error is caused I think because the application does not know what service to use when two are exported. If I comment "GunProviderServerConfig" and "rmiProxyFactoryBean2" such that I have only the ClientService, the app will work.
I ran into the same issue yesterday but it worked for me this morning. consider moving the two exporters to the same configuration class

Could not handle mustUnderstand headers: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault

I went through links like: SOAPFaultException "MustUnderstand headers (oasis-200401-wss-wssecurity-secext-1.0.xsd) are not understood", but still struggling.
I'm using Spring Boot v2.2.2..RELEASE and SOAP project.
I am loading two different WSDL file into my project. One URL Generates to http://localhost:8080/employee/employee-soap which works fine. But http://localhost:8080/student/student-soap this gives below error.
2020-02-17 15:31:00.241 WARN 20236 --- [nio-8080-exec-5] o.s.w.soap.server.SoapMessageDispatcher : Could not handle mustUnderstand headers: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault
JavaCode:
#EnableWs
#Configuration
public class AppConfig extends WsConfigurerAdapter {
#SuppressWarnings({ "rawtypes", "unchecked" })
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/*");
}
#Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_11);
messageFactory.afterPropertiesSet();
return messageFactory;
}
#Bean("empXSD")
public XsdSchema organizationSchema() {
return new SimpleXsdSchema(new ClassPathResource("/xsd/employee.xsd"));
}
#Bean(name = "employee")
public DefaultWsdl11Definition defaultWsdl11Definition(#Qualifier("empXSD") XsdSchema schema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("employee");
wsdl11Definition.setLocationUri("employee/employee-soap");
wsdl11Definition.setTargetNamespace("urn:example.com:dms:wsdls:employee");
wsdl11Definition.setSchema(schema);
wsdl11Definition.setCreateSoap11Binding(true);
return wsdl11Definition;
}
#Bean
#Qualifier(value="stuXSD")
public XsdSchema stuSchema() {
return new SimpleXsdSchema(new ClassPathResource("/xsd/student.xsd"));
}
#Bean(name = "student")
public DefaultWsdl11Definition geographyWsdl11Definition(#Qualifier("stuXSD") XsdSchema schema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("student");
wsdl11Definition.setLocationUri("student-soap");
wsdl11Definition.setTargetNamespace("urn:example.com:dms:wsdls:student");
wsdl11Definition.setSchema(schema);
wsdl11Definition.setCreateSoap11Binding(true);
return wsdl11Definition;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(new Interceptor(endpoints, req));
}
}
Code:
#Configuration
public class SimpleMustUnderstandEndpointInterceptor implements SoapEndpointInterceptor{
private final String SAMPLE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
#Override
public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
}
#Override
public boolean understands(SoapHeaderElement header) {
if(header.getName().getNamespaceURI().equalsIgnoreCase(SAMPLE_NS)) {
return true;
}
return false;
}
}
Per observation, looks like even this SoapEndpointInterceptor is not calling, before to that only its giving error.
During calling SOAP endpoint, below header information is going and its giving Fault as I mentioned above. Any pointers ?
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-
518482F2CDC2F635FF158202815227129"><wsse:Username>aispoc_usr1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
username-token-profile-1.0#PasswordText">aispoc_usr1</wsse:Password><wsse:Nonce
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-
message-security-1.0#Base64Binary">/fdGCEilz/dkVeZE05b7LQ==</wsse:Nonce>
2020-02-18T12:15:52.271Z
You can try below config that would solve the issue.
#Bean
public Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor security = new Wss4jSecurityInterceptor();
security.setValidationActions("NoSecurity");
security.setValidateRequest(false);
security.setValidateResponse(true);
return security;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(securityInterceptor());
}
I was able to find the solution looking at https://docs.spring.io/spring-ws/site/apidocs/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.html and https://memorynotfound.com/spring-ws-username-password-authentication-wss4j/.
I simply used below bean and its started working fine.
#Bean
public Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor security = new Wss4jSecurityInterceptor();
security.setSecurementActions("NoSecurity");
security.setSecurementPasswordType(WSConstants.PW_TEXT);
return security;
}

Spring boot ws: 2 endpoints, one with MTOM enabled, one with MTOM disabled

I'd like to create a Spring Boot ws application with two endpoints, but I need one with MTOM enabled (for newer clients) and the other with MTOM disabled (for older clients).
The two endpoints should be the same in any other way.
Please, tell me if this is possible, and if yes, give me any hints how to do it.
Thanks in advance
You can do this simply duplicating your schema and endpoint (only the namespace should differ) using the configuration below. The only limitations are that the two endpoints share the same uri (host/ws/NotMtomServices.wsdl and host/ws/MtomServices.wsdl)
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurationSupport {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "NotMtomServices")
public DefaultWsdl11Definition defaultWsdl11DefinitionILServices(XsdSchema notMtomServicesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("ILPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace(NotMtomServices.NAMESPACE_URI);
wsdl11Definition.setSchema(notMtomServicesSchema);
return wsdl11Definition;
}
#Bean(name = "MtomServices")
public DefaultWsdl11Definition defaultWsdl11DefinitionILServicesMTOM(XsdSchema mtomServicesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("ILPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace(MtomServices.NAMESPACE_URI);
wsdl11Definition.setSchema(mtomServicesSchema);
return wsdl11Definition;
}
#Bean
#Override
public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
List<MethodArgumentResolver> argumentResolvers = new ArrayList<MethodArgumentResolver>();
argumentResolvers.addAll(methodProcessors());
List<MethodReturnValueHandler> returnValueHandlers = new ArrayList<MethodReturnValueHandler>();
returnValueHandlers.addAll(methodProcessors());
DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
adapter.setMethodArgumentResolvers(argumentResolvers);
adapter.setMethodReturnValueHandlers(returnValueHandlers);
return adapter;
}
#Bean
public List<MarshallingPayloadMethodProcessor> methodProcessors() {
List<MarshallingPayloadMethodProcessor> retVal = new ArrayList<MarshallingPayloadMethodProcessor>();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(NotMtomServices.NAMESPACE_URI);
marshaller.setMtomEnabled(false);
retVal.add(new MarshallingPayloadMethodProcessor(marshaller));
Jaxb2Marshaller marshallerMTOM = new Jaxb2Marshaller();
marshallerMTOM.setContextPath(MtomServices.NAMESPACE_URI);
marshallerMTOM.setMtomEnabled(true);
retVal.add(new MarshallingPayloadMethodProcessor(marshallerMTOM));
return retVal;
}
#Bean(name="notMtomServicesSchema")
public XsdSchema ServicesSchema() {
return new SimpleXsdSchema(new ClassPathResource("not_mtom_services.xsd"));
}
#Bean(name="mtomServicesSchema")
public XsdSchema ServicesSchemaMTOM() {
return new SimpleXsdSchema(new ClassPathResource("mtom_services.xsd"));
}
}

Spring WS: How to apply Interceptor to a specific endpoint

I have multiple working SOAP Web Services on a Spring application, using httpBasic authentication, and I need to use WS-Security instead on one of them to allow authentication with the following Soap Header.
<soap:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security></soap:Header>
Current WSConfiguration was done according to https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-ws/ giving something like
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean dispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
return new ServletRegistrationBean(servlet, "/services/*");
}
#Bean(name = "SOAP1")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema soap1) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("Soap1");
wsdl11Definition.setLocationUri("/soap1/");
wsdl11Definition.setTargetNamespace("http://mycompany.com/hr/definitions");
wsdl11Definition.setSchema(soap1);
return wsdl11Definition;
}
#Bean
public XsdSchema soap1() {
return new SimpleXsdSchema(new ClassPathResource("META-INF/schemas/hr.xsd"));
}
}
and Web Security according to http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/ looks like this
#EnableWebSecurity
#Configuration
public class CustomWebSecurityConfigurerAdapter extends
WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth
.inMemoryAuthentication()
.withUser("user1")
.password("password")
.roles("SOAP1")
.and()
.withUser("user2")
.password("password")
.roles("SOAP2");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeUrls()
.antMatchers("/soap/soap1").hasRole("SOAP1")
.antMatchers("/soap/soap2").hasRole("SOAP2")
.anyRequest().authenticated()
.and().httpBasic();
}
}
After some searches, I found that Wss4J provides a UsernameToken authentication, but can't figure out how to use it. What I'm trying to do is the following
https://sites.google.com/site/ddmwsst/ws-security-impl/ws-security-with-usernametoken
but without XML files with bean definitions.
What I plan to do:
Create the Callback Handler.
Create a Wss4jSecurityInterceptor, setting "setValidationActions" to "UsernameToken", "setValidationCallbackHandler" to my callback handler, and then add it by overriding addInterceptors on my WebServiceConfig.
(I tried something like that, but I just realised my callback was using a deprecated method)
Problem : Even if it works, it would then apply to all my webservices on "WebServiceConfig".
Update :
The implementation does work, but as expected it is applied to all my Web Services. How could I add my interceptor only to 1 Web Service ?
Following, the code I added in WebServiceConfig
#Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws IOException, Exception{
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
interceptor.setValidationActions("UsernameToken");
interceptor.setValidationCallbackHandler(new Wss4jSecurityCallbackImpl());
return interceptor;
}
#Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
try {
interceptors.add(wss4jSecurityInterceptor());
} catch (Exception e) {
e.printStackTrace();
}
}
Sorry, I totally forgot to answer this, but in case it helps someone :
We got it working by creating a new SmartEndpointInterceptor, and applying it only to our endpoint:
public class CustomSmartEndpointInterceptor extends Wss4jSecurityInterceptor implements SmartEndpointInterceptor {
//CustomEndpoint is your #Endpoint class
#Override
public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
if (endpoint instanceof MethodEndpoint) {
MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint;
return methodEndpoint.getMethod().getDeclaringClass() == CustomEndpoint.class;
}
return false;
}
}
instead of adding a wss4j bean to the WebServiceConfig, we added our SmartEndpointInterceptor :
#Configuration
public class SoapWebServiceConfig extends WsConfigurationSupport {
//Wss4jSecurityCallbackImpl refers to an implementation of https://sites.google.com/site/ddmwsst/ws-security-impl/ws-security-with-usernametoken
#Bean
public CustomSmartEndpointInterceptor customSmartEndpointInterceptor() {
CustomSmartEndpointInterceptor customSmartEndpointInterceptor = new CustomSmartEndpointInterceptor();
customSmartEndpointInterceptor.setValidationActions("UsernameToken");
customSmartEndpointInterceptor.setValidationCallbackHandler(new Wss4jSecurityCallbackImpl(login, pwd));
return customSmartEndpointInterceptor;
}
[...]
}
Hope this is clear enough :)
It is worthworthy to note that whether is the result of the method shouldIntercept, the program would execute anyways the handleRequest method.
This can be dangerous, for example, in the login process.
In a project that I'm developing, we have only two endpoints:
UserLoginEndpoint
SomeGeneralEndpoint
The login would be invoked only for logging in purposes and will produce a token that I'll have to parse somehow from the request (this is done via an interceptor, the only one that we need in the application).
Suppose we have the following interceptor, just like Christophe Douy proposed and that our class of interest would be the UserLoginEndpoint.class
public class CustomSmartEndpointInterceptor extends Wss4jSecurityInterceptor implements SmartEndpointInterceptor {
//CustomEndpoint is your #Endpoint class
#Override
public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
if (endpoint instanceof MethodEndpoint) {
MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint;
return methodEndpoint.getMethod().getDeclaringClass() == UserLoginEndpoint.class;
}
return false;
}
If this returns true, by all means, that's good and the logic defined in the handleRequest method will be executed.
But where's my issue?
For my specific problem, I'm writing an interceptor that should get in the way only if the user has already logged in. This means that the previous snippet code should be the following
public class CustomSmartEndpointInterceptor extends Wss4jSecurityInterceptor implements SmartEndpointInterceptor {
//CustomEndpoint is your #Endpoint class
#Override
public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
if (endpoint instanceof MethodEndpoint) {
MethodEndpoint methodEndpoint = (MethodEndpoint)endpoint;
return methodEndpoint.getMethod().getDeclaringClass() != UserLoginEndpoint.class;
}
return false;
}
And if that would be true, the handleRequest method would be executed (my implementation is below)
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
System.out.println("### SOAP REQUEST ###");
InputStream is = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = null;
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
is = new ByteArrayInputStream(payload.getBytes());
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(is);
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
#Override
public String getNamespaceURI(String prefix) {
switch(prefix) {
case "soapenv":
return "http://schemas.xmlsoap.org/soap/envelope/";
case "it":
return "some.fancy.ws";
default:
return null;
}
}
#Override
public String getPrefix(String namespaceURI) {
return null;
}
#Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
XPathExpression expr = xpath.compile("//*//it:accessToken//text()");
Object result = expr.evaluate(doc, XPathConstants.NODE);
Node node = (Node) result;
String token = node.getNodeValue();
return authUtility.checkTokenIsValid(token);
}
But what happens if shouldIntercept returns false? If the handleRequest method, which is mandatory to implement if you "implements" SmartPointEndPointInterceptor, returns true, the invocation chain will keep on; but if it returns false, it will stop there: I'm in the second case, but the handleRequest still gets executed.
The only workaround that I found is to add a property in the MessageContext which has an arbitrary key and a corresponding value which is the one returned from the shouldIntercept method.
Then negate that value in the very first lines of your handleRequest's implementation to force the return true and have the invocation chain
if (!(Boolean)messageContext.getProperty("shouldFollow")) {
return true;
}
Of course, this will work in projects where only one interceptor is needed (i.e., in my case just to verify if the user is really logged in) and there are many other factors that might influence everything but I felt it was worthy to share in this topic.
I apologize in advance if I made a mistake in answering here instead of opening a new question

Spring-boot jersey : resources not autodiscover

I try to use Spring-boot with jetty and jersey.
No problem with the jetty part. I can start server and spring resources are running (trace, metrics,info,beans,....) but my resources didn't run.
My configuration files are :
Launcher.java
#Configuration
#PropertySource("classpath:application.properties")
#EnableAutoConfiguration
#ComponentScan(basePackages = {"com.fdilogbox.report.serveur"})
public class Launcher extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Launcher.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Launcher.class);
}
#Bean
public ServletRegistrationBean jerseyServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/api/*");
registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, ResourcesConfiguration.class.getName());
return registration;
}
#Bean
public EmbeddedServletContainerFactory containerFactory() {
final JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory = new JettyEmbeddedServletContainerFactory() {
#Override
protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(Server server) {
return new JettyEmbeddedServletContainer(server);
}
};
jettyEmbeddedServletContainerFactory.addServerCustomizers(new JettyConfiguration());
return jettyEmbeddedServletContainerFactory;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
JettyConfiguration.java
public class JettyConfiguration implements JettyServerCustomizer {
#Override
public void customize(Server server) {
WebAppContext webAppContext = (WebAppContext) server.getHandler();
try {
// Load configuration from resource file (standard Jetty xml configuration) and configure the context.
createConfiguration("/jetty.xml").configure(webAppContext);
createConfiguration("/jetty-rewrite.xml").configure(server);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private XmlConfiguration createConfiguration(String xml) throws IOException, SAXException {
return new XmlConfiguration(Launcher.class.getResourceAsStream(xml));
}
}
ResourcesConfiguration.java
public class ResourcesConfiguration extends ResourceConfig {
public ResourcesConfiguration() {
super();
PackageNamesScanner resourceFinder = new PackageNamesScanner(new String[]{"com.fdilogbox.report.serveur.business.resources"}, true);
registerFinder(resourceFinder);
register(JacksonFeature.class);
}
}
and my resources file :
#Path("builder")
#Component
public class ReportBuilderResource {
#Autowired
private ReportBuilderService reportBuilderService;
#GET
#Path("list")
#Produces(MediaType.APPLICATION_JSON)
public String[] findAll() {
return reportBuilderService.findAllReport();
}
}
If I try to acces "localhost:9090/api/builder/list" I get an 404 error.
But if I try "localhost:9090/bean" I get all bean on JSon format.
I think I have an error in my conf but I don't know where.
I found my mistake : management port is 9090 but the normal resources port is 8090.

Categories

Resources