i have a web service working like this:
#WebService(serviceName = "TempService")
public class TempService {
#WebMethod(operationName = "addBarkod")
public Boolean addBarkod(#WebParam(name = "barkod") Barkod barkod) {
System.out.println(barkod.getBarkodNo());
}
}
and the Barkod class as:
public class Barkod {
private String barkodNo;
// there are constructors and getters, setters etc. nothing fancy //
}
with this structure my web service can be called with soapUI wtihout a problem. the problem is when i want to annotate my model class with JAXB annotations like:
#XmlType(name="barkod")
#XmlRootElement(name="barkod")
#XmlAccessorType(XmlAccessType.FIELD)
i can deploy this to glassfish 3.1 and soapUI generates new client request with new structure but when it comes to do "barkod.getBarkodNo();" at addBarkod operation it throws a NullPointerException. i looks like the XML i sent to the web service does not create a proper Barkod object.
do i have to do with web service class or something?
i think problem caused because soapUI generates the request automatically from my WSDL. when i annotate my class with #XmlRootElement without the namespace clause it does not map given XML to may object. i assign #XmlRootElemen(namespace="") and my problem goes away.
thanks for responses anyway.
Related
(https://github.com/aashrai/brahma-dao), similar to this DAO generator can we do annotation processing to generate a client for a rest controller ?
PS : I am using Spring Boot with gradle.
Domino-rest can do that, it generates a client from a jax-rs interface resource.
the generated client works in JVM, and will automatically map JSON responses/requests.
a short sample can look like this
the jax-rs interface
#RequestFactory
public interface MoviesService {
#Path("library/movies/:movieName")
#GET
Movie getMovieByName(String movieName);
#Path("library/movies")
#GET
List<Movie> listMovies();
#Path("library/movies/:name")
#PUT
void updateMovie(#RequestBody Movie movie);
}
and the generated client can be used like this
MoviesServiceFactory.INSTANCE
.getMovieByName("hulk")
.onSuccess(movie -> {
//do something on success
})
.onFailed(failedResponse -> {
//do something on error
})
.send();
there is lots of supported features and enough documentation to get you started.
please note that this is still under development and is still in SNAPSHOT.
I am developing a restful web service in Java. One of my service needs to call a SOAP service and for this I need to build an XML request. My question is that "I want to build that xml file in a seperate helper class, is this a convenient way to do? " I am using Spring for MVC, is there any advantages of it here that I can implement?
Example pseucode;
#RestController
#RequestMapping("/rest/menu")
public class MenuController {
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity<String> createUser(#RequestBody JSONObject userInfo){
//Here I need to make a Soap call to retrieve some information
MyXMLBuilder myXMLBuilder = new MyXMLBuilder();
String soapRequest = myXMLBuilder.build();
}}
and here the helper class;
public class MyXMLBuilder(){
public String build(){
//xml build implementation
}}
Usually, to consume a SOAP WebService, you will create the required stubs with the wsimport tool, which is within your Java SDK in the /bin folder.
Within your favourite terminal, switch to your desired folder for the stubs to be created in and type:
wsimport -keep -verbose http://example.com/myservice?wsdl
You can then use the Service Stubs like this
MyServiceImplService myService = new MyServiceImplService();
MyService port = myService.getMyServiceImplPort();
port.yourFunction(param1, param2);
I am struggling big time offering a web service based on some WSDL file received from a customer. As described in details here, the WSDL file returned when appending a ?wsdl to the service URL like
http://never.mind/SomeService?wsdl
seems to be misinterpreted by SoapUI and this again prevents the customer from using the service!
I was now hoping that someone could help me understand if it is possible to make the get WSDL endpoint return the original WSDL file instead of some Apache CXF digested version?
Update: I just read somewhere that there is a WSDLGetInterceptor taking care of the get WSDL requests - can I maybe override that one?
I chose to override the getDocument method of the WSDLGetUtils class being used by the WSDLGetInterceptor. My version of the utils class MyWSDLGetUtilsis put into action via this interceptor:
public class WsdlGetSoapInterceptor extends AbstractSoapInterceptor {
public WsdlGetSoapInterceptor() {
super(Phase.READ);
addBefore(WSDLGetInterceptor.class.getName());
}
/** {#inheritDoc} */
#Override
public void handleMessage(final SoapMessage message) throws Fault {
message.setContextualProperty(WSDLGetUtils.class.getName(), MyWSDLGetUtils.Instance);
}
}
As far as I understood, you can introduce:
#Stateless
#WebService
public class MyWebServiceEndpoint {
#Inject SomeBean aBean;
#WebMethod
public String getSomething() {
return "something";
}
}
and when application deployed, the WebService is exposed in the Application Server (such as WebSphere). Then what is the URL of WSDL, where other applications can find my service?
The URL of your WSDL on the server should be in the following format:
http://hostname:port/contextRoot/MyWebServiceEndpoint?WSDL
But this is running under the assumption that the url-pattern attribute of the endpoint entity in your sun-jaxws.xml file uses the same name as your web service class.
Just a hint to the first answer/URL,
In some cases the "context Root" get excluded from the webservice url after deployment.
I can't say for other application servers but for WebLogic and EJB web service URL follow the following default pattern:
http://host:port/'className'/'className'+Service
where 'className' is the simple name of the Java class implementing the web service.
You can easily override the end of the URL by setting the serviceName attribute in the #WebService annotation. If you need to change the root context you must package your web service as an EJB jar embedded in an EAR and use the WebLogic specific deployement descriptor (which I would avoid at all costs).
Hope it helps :)
you need to publish it, You can have a Publisher class like this:
import javax.xml.ws.Endpoint;
//Endpoint publisher
public class Publisher {
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/webserv/Test", new FilenetWebService());
}
}
I have 2 questions:
1. Can I create one class, annotate it with JAXB annotations(for XML support) and declare in web.xml
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
for JSON (Jackson library) support? Or I need to create separately two classes for JSON and XML?
Or may be exist some more elegant way to cause REST service to return both JSON and XML?
2. How I can programmatically choose what type to return (JSON or XML)?
Thanks.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
Can I create one class, annotate it with JAXB annotations(for XML support) and declare in web.xml for JSON (Jackson library) support?
You can always use an Application class to specify a MessageBodyReader/MessageBodyWriter for the JSON binding. I believe Jackson provides an implementation in its jar. Below is an example of an Application class that specifies MOXy as the JSON provider:
package org.example;
import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
public class CustomerApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>(2);
set.add(MOXyJsonProvider.class);
set.add(CustomerService.class);
return set;
}
}
Or I need to create separately two classes for JSON and XML?
EclipseLink JAXB (MOXy) offers native XML binding and is designed to enable you to use the same object model for both JSON and XML. You can integrate it into your JAX-RS application using the MOXyJsonProvider class:
http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html
How I can programmatically choose what type to return (JSON or XML)?
Server Side
You can specify that your service offers both XML and JSON messages using the #Produces annotation.
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Path("{id}")
public Customer read(#PathParam("id") long id) {
return entityManager.find(Customer.class, id);
}
For More Information
http://blog.bdoughan.com/2012/03/moxy-as-your-jax-rs-json-provider.html
Client Side
You can use the MediaType to indicate the type of message. Below is an example using Jersey client APIs. Note how the URL is the same, just the requested media type is different.
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/CustomerService/rest/customers");
// Get XML response as a Customer
Customer customer = resource.path("1")
.accept(MediaType.APPLICATION_XML)
.get(Customer.class);
System.out.println(customer.getLastName() + ", "+ customer.getFirstName());
// Get JSON response as a Customer
Customer customer = resource.path("1")
.accept(MediaType.APPLICATION_JSON)
.get(Customer.class);
System.out.println(customer.getLastName() + ", "+ customer.getFirstName());
For More Information
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-55.html
If your client wants to use a part of the URL to configure the response type, you can use a Servlet filter.
An easy way to implement overriding the representation (media type) could use a URL query parameter:
/resources/todo?format=json
The Servlet filter parses the URL query parameters, and if a format=json is present, replaces or adds the accept header "application/json".
No need for seperate classes, what you need is seperate methods:
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Todo getXML() {
Todo todo = new Todo();
todo.setSummary("This is my first todo");
todo.setDescription("This is my first todo");
return todo;
}
Then in the client side, when you request for the service, you indicate in what format you want it:
// Get XML
System.out.println(service.path("rest").path("todo").accept(MediaType.TEXT_XML).get(String.class));
// Get XML for application
System.out.println(service.path("rest").path("todo").accept(MediaType.APPLICATION_XML).get(String.class));
// Get JSON for application
System.out.println(service.path("rest").path("todo").accept(MediaType.APPLICATION_JSON).get(String.class));