I am implementing a Code first cxf web service. How does cxf decide the soap:address part of generated wsdl ? Is it using the hostname from the deployed machine ?
Also, can I change the endpoint protocol from http to https programmatically or by-configuration on the deployed application ?
You can use Spring for this.
you must create an impl for the interface service.
#WebService(endpointInterface = "com.services.MyAwesomeService")
public class MyAwesomeServiceImpl implements MyAwesomeService {
#Override
public String sayHi(String text) {
return "Hello " + text;
}
}
And config vía Spring.
#Configuration
public class ServiceConfig {
#Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
#Bean(name = "myAwesomeService")
public MyAwesomeServiceImpl myAwesomeService() {
return new MyAwesomeServiceImpl();
}
#Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), myAwesomeService());
endpoint.publish("/MyAwesomeService");
return endpoint;
}
}
After doing this. You will have your service published in the path /MyAwesomeService.
To configure the HTTPS protocol, I recommend you configure it in the application container (Tomcat) or dedicated front (Apache, F5, etc.)
Related
I have a streaming (sse) api up and running. It's realized in java and spring boot. The code is given below:
#SpringBootApplication
#RestController
#RequestMapping("sse")
public class SseApplication {
public static void main(String[] args) {
SpringApplication.run(SseApplication.class, args);
}
#GetMapping(path = "/stream-flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamFlux() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> "Flux - " + LocalTime.now().toString());
}
#GetMapping("/stream-sse")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("periodic-event")
.data("SSE - " + LocalTime.now().toString())
.build());
}
}
When it is directly checked through browser and curl, the streaming response is as expected.
I published it on wso2 apim by publisher portal following the official documentation. Then I tested that api through wso2 apim gateway. It does not returning anything just like as it hangs
I have an AWS instance that uses Elastic Load Balancing (ELB). I am using Spring MVC with secure login. The ELB is configured for 80 HTTP >> 8080 HTTP and 443 HTTPS >> 8080 HTTP. The ELB is doing all of the HTTPS encryption. I want port 80 to redirect to 443 so all requests to the web service are HTTPS. I used "use-forward-headers=true" and "x-forwarded-proto: https" in my application.properties. When I type test.mydomain.com the ELB/Webservice redirects to HTTPS but goes to the /login page and not my home page. If I type test.mydomain.com/home it redirects to HTTPS and correctly goes to the /home page. My #Controller page appears to be correctly set to always direct to the /home page. Not sure why it directs to /login. I suspect it is all of the redirecting going on between the ELB and Spring MVC. Any ideas??
My controller code is,
#Controller
public class AdminController {
private static final Logger logger = (Logger)
LoggerFactory.getLogger(AdminController.class);
// Home Page
#RequestMapping(value = {"", "/", "/home"}, method=RequestMethod.GET)
public String home(Model model) {
return "home";
}
// Login Page
#RequestMapping(value = {"/login"}, method=RequestMethod.GET)
public String login(Model model) {
firsttime = true;
return "login";
}
}
My WebSecurityConfig code is,
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception{
// Allows access for .css, .js, and .images files
http.authorizeRequests()
.antMatchers("/resources/**")
.permitAll()
.anyRequest()
.permitAll();
// Access management for all other requests
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/home")
.invalidateHttpSession(true)
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDS).passwordEncoder(passwordEncoder());
}
#Override
protected UserDetailsService userDetailsService() {
return userDS;
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
#Autowired
UserDetailsService userDS;
}
My application.properties is,
# Admininstration Web Server Parameters
security.require-ssl=true
server.use-forward-headers = true
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
How to publish a web service class with #WebServiceProvider?What is the endpoint URL in this case?
Could we generate wsdl with #WebServiceProvider as in the case with
#WebService?What does the "wsdlLocation" attribute mean in #WebServiceProvider?
For instance
#ServiceMode(value = Service.Mode.MESSAGE)
#WebServiceProvider(portName = "ProviderPort",serviceName = "ProviderService",
targetNamespace = "http://bean/")
public class WebServiceProviderImpl implements Provider<SOAPMessage>
Simplest way is-
package server;
import javax.xml.ws.Endpoint;
public class Server {
protected Server() throws Exception {
System.out.println("Starting Server");
System.out.println("Starting SoapService1");
Object implementor = new WebServiceProviderImpl();
String address = "http://localhost:8123/SoapContext/SoapPort1";
Endpoint.publish(address, implementor);
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
The URL is "address". As far as I understand you can specify it as you like, as long as the port is free.
Alternatively, you could use JAXWsServerFactoryBean which is a part of CXF.
You would do the same thing as you would with an SEI.
And yes, it does generate a WSDL for you.
You can create your client stubs from it using wsimport just like an SEI
I am a beginner in JBoss.
I am making a database application that uses JPA. For exposing the same I have to expose a SOAP based web service. I followed the basic JBoss tutorial
http://docs.jboss.org/tools/4.1.0.Final/en/ws_soap_reference/html/topdown.html#bottomupws
to create a web service.
To consume the web service I created a client using the following tutorial.
http://docs.jboss.org/tools/4.1.0.Final/en/ws_soap_reference/html/client.html
But when I am executing this client I am getting a 404 error. The exact same issue is reported on the JBoss community
https://community.jboss.org/thread/164471?tstart=0
My Webservice bean looks something like this:
#WebService(name = "Management", targetNamespace = "http://www.example.org/Management")
public class Management {
#PersistenceContext
private EntityManager em;
#EJB(name = "ejb/ar/ClientEjb", mappedName = "ejb/ar/ClientEjb")
ClientRegistration clientReg;
#WebMethod(action = "http://www.example.org/Management/getAccount")
#WebResult(name = "getAccountResponse", partName = "getAccountResponse")
public String getAccount(
#WebParam(name = "getAccountRequest", partName = "getAccountRequest") String param) {
return "account-56789012354349";
}
#WebMethod(action = "http://www.example.org/Management/addClient")
public List<Client> addClient
(#WebParam(name = "clientId", partName = "clientId") long clientId ){
//For time being let's forget this method.
return null;
}
}
The web.xml has:
<servlet>
<display-name>Management</display-name>
<servlet-name>Management</servlet-name>
<servlet-class>org.jboss.tools.examples.service.Management</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Management</servlet-name>
<url-pattern>/Management</url-pattern>
</servlet-mapping>
The Management.wsdl has:
<wsdl:service name="ManagementService">
<wsdl:port name="ManagementPort" binding="tns:ManagementServiceSoapBinding">
<soap:address location="http://localhost:9090/Management"/>
</wsdl:port>
</wsdl:service>
The ClientSample.java is:
public class ClientSample {
public static void main(String[] args) {
System.out.println("***********************");
System.out.println("Create Web Service Client...");
ManagementService service1 = new ManagementService();
System.out.println("Create Web Service...");
Management port1 = service1.getManagementPort();
System.out.println("Call Web Service Operation...");
System.out.println("Server said: " + port1.getAccount(null));
System.out.println("Server said: " + port1.addClient(0));
//Please input the parameters instead of 'null' for the upper method!
System.out.println("Create Web Service...");
Management port2 = service1.getManagementPort();
System.out.println("Call Web Service Operation...");
System.out.println("Server said: " + port2.addClient(Long.parseLong(args[1])));
System.out.println("Server said: " + port2.getAccount(null));
//Please input the parameters instead of 'null' for the upper method!
System.out.println("***********************");
System.out.println("Call Over!");
}
}
Exception is like below:
***********************
Create Web Service Client...
Create Web Service...
Call Web Service Operation...
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 404: Not Found
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.checkStatusCode(HttpTransportPipe.java:196)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:168)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:83)
at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:105)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:587)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:546)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:531)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:428)
at com.sun.xml.internal.ws.client.Stub.process(Stub.java:211)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:138)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:98)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:110)
at com.sun.proxy.$Proxy29.getAccount(Unknown Source)
at org.jboss.tools.examples.service.jaxws.clientsample.ClientSample.main(ClientSample.java:20)
I feel this may be because the service is not getting published, but I can't find I way to publish it.
I am using jboss-as-7.1.0.Final Runtime Server.
Note: Just to see if my Client code is correct I published the bean using
Endpoint.publish("http://localhost:9090/Management", new org.jboss.tools.examples.service.Management());
in the client code itself. The web service could be hit, but this is not in the application context of my application.
how can I access a webservice through a basic http authentification? I am using the netbeans built in webservice client features. But when I try to access the webservice, I get an exception with a 401 auth failed error message.
How can I pass the right username and password?
Thank you!
You could use BindingProvider or WSBindingProvider class to access a Web Service through a basic http authentification.
The code is as follows.
XxxService service = new XxxService();
Xxx port = service.getXxxPort();
Map<String, Object> reqContext = ((BindingProvider)port).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "username");
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "password");
You can also provide your own Authenticator. That way it will work even if the WDSL itself is protected by basic HTTP authentication.
#WebServiceRef(wsdlLocation = "https://laka/sito?wsdl")
static XxxService service;
public static void main(String[] args) {
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
});
service = new XxxService();
Xxx port = service.getXxxPort();
// invoke webservice and print response
XxxResponse resp = port.foo();
System.out.println(resp.toString());
}