Generate DTO classes from XSD or by simple POJO classes - java

I have been working with an enterprise application, where we use SOAP and RESTful Webservices. At some point we have planned to migrate SOAP to RESTful service in order to produce JSON MediaType as response. For SOAP we have been generating dto classes from XSD files. In case of Restful implementation i can directly use POJO classes as my request and response.
Here XML definition is not required. So is it necessary to create new DTO classes generated from xsd or can i create simple POJO classes and use as request and response.
I can configure POJO maping in web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Related

How to fix 'cannot be cast to javax.servlet.Servlet' error while trying to package REST App with Servlet

I am trying to setup Angular 7 with a maven based back-end java project into a single war file. At the moment I am trying to configure the web.xml file where I am currently having this problem. I am not sure at all if my approach is valid or 'good' therefore I will first describe what I am trying to do (if you think better on this aspect please do correct me).
So I have a couple of JAX-RS classes which I'd like to serve as a REST API. For this purpose I have created corresponding javax.ws.rs.core.Application classes to provide these REST components. Then I am including the Application classes in the web.xml file. Below are the files:
web.xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<url-pattern>/rmz/*</url-pattern>
</servlet-mapping>
Another variation of web.xml that I tried
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>backend.backendservice.StammSolvaraJahrRestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
<url-pattern>/rmz/*</url-pattern>
</servlet-mapping>
Application class
public class StammSolvaraJahrRestApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> sets = new HashSet<>();
sets.add(StammSolvaraJahrRest.class);
return sets;
}
}
The error that I get is: java.lang.ClassCastException: backend.backendservice.StammSolvaraJahrRestApplication cannot be cast to javax.servlet.Servlet and if I remove the <servlet-class> then I'll get No servlet class has been specified for servlet. I am following https://docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF183 and How to deploy a JAX-RS application? among others but it seems not to be working.
There are two ways to define your JAX-RS servlet.
1) With Application Subclass like the one you have, you can skip the web.xml config and just add the application annotation
#ApplicationPath("resources")
public class StammSolvaraJahrRestApplication extends Application
2) With web.xml config
<servlet>
<display-name>JAX-RS Servlet</display-name>
<servlet-name>package.hierarchy.StammSolvaraJahrRestApplication</servlet-name>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>package.hierarchy.StammSolvaraJahrRestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JaxRSServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
If you skip the servlet mapping from the last one, it will use your your #ApplicationPath specified value, or "/resources" if the previous one is missing.
The problem is just what it says. This line in your web.xml requires a javax.servlet.Servlet:
<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
Since an Application is not a javax.servlet.Servlet, you're getting the error at runtime when your XML file is processed.
If you can, I would suggest that you start with a Spring Boot starter application. Spring Boot handles all of this for you. It can even embed a Tomcat server inside a jar file so that you can run your server like a simple Java application. Doing this would save you having to worry about what you're dealing with here.

Apache Camel CXF SOAP WS WSDL

In my application I am trying to expose one soap web service and doing basic operations. This is what I have done:
Created Interface with soap operations as per JAX-WS standard. Added all needed annotations
in WEB.xml added
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservices/*</url-pattern>
</servlet-mapping>
created one route
from uri="cxf:/myservice?serviceClass="x.x.x.myInterface&dataFormat=PAYLOAD"
I am able to see the WSDL details in browser (localhost:8080/pro/webservices/myservice?wsdl), but if I hit the service using SOAP UI project my request is not coming through. I'm getting the below error in SOAP UI project:
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>org/apache/cxf/frontend/MethodDispatcher</faultstring>
</soap:Fault>
If I use dataFormat=MESSAGE my service is invoked by SOAPUI and getting response. But my WSDL is not coming in browser. Please tell which dataFormat i have to use in cxf component.
It jar issue. After using latest Jar it is working fine

JsonParseExceptionMapper not called by Jersey

I use Jersey and Jackson to implement RESTful services provided by my server. Data is exchanged between the client and server as JSON documents. Jackson does the mapping between the JSON documents and the POJOs. This works well.
But I ran into one issue. When calling a service with a malformed JSON document, the server returns with an 500 error. I would expect a 400 BAD-Request error instead. Some searching in the Jersey docs showed me that ExceptionMappers can be used to archive this behavior. I also found out that Jackson already has a implementation a JsonParseExceptionMapper but it never gets called.
Do I have to register the mapper and if so how can I do this outside of the source code.?
Ok I found out how to register the mapper classes.
In your web.xml where Jersery ServletContainer is registered you have to pass the Jackson package name org.codehaus.jackson.jaxrs beside your package name e.g. com.example.myapp.api;. The server then scans these packages on start up and registers the listener it find.
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.example.myapp.api;org.codehaus.jackson.jaxrs</param-value>
</init-param>
</servlet>

Logging JSON request and response for jersey

I have a JAVA web application application, which exposes RESTful apis. My requirement is to log all the JSON requests and responses that are handled by the server.
Is there any parameter like -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true for JAX-WS?
I am also exploring AOP approach. What method signature should I add in the AOP pattern?
I am using Tomcat server and jersey for the JAX-RS implementation.
use LoggingFilter. Just add the following to your web.xml:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<!-- Enable Jersey tracing support in Glassfish -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
This worked for me (Jersey 2.x)

Spring MVC: RESTful web services + BlazeDS integration possible in the same web application?

I have a Spring MVC web application which provides RESTful web services via a controller class (annotated with #Controller) which has methods mapped to specific request types and signatures via #RequestMapping annotations.
I have attempted to integrate a BlazeDS service destination into the mix by 1) adding the HttpFlexSession listener to the web.xml, 2) adding the flex:message-broker and flex:remoting-destination declarations to my Spring application context configuration file, and 3) adding a generic /WEB-INF/flex/services-config.xml.
The above BlazeDS integration steps appear to have hosed my RESTful web services, in that it appears that requests are no longer being routed to the controller methods.
Is it even possible to do this, i.e, to have a single web application which 1) services HTTP requests via request mapped controller methods and 2) services remote object method calls (i.e. from a Flex client) via a BlazeDS service? If so then can anyone tell me what it may be that I'm doing wrong?
Thanks in advance for your help.
Yes, it's possible, but it requires a little extra configuration.
Essentially you need to create two seperate dispatchers, each with a different path.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<name>flex</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<name>spring-mvc</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
Now requests to http://yourapp/app/somewhere are routed to Spring MVC, and requests to http://yourapp/messagebroker are routed through BlazeDS.
Also, you'll need to split out your spring context files into three:
A common context (named applicationContext.xml in the above example)
One for Spring MVC (named spring-mvc-servlet.xml in the above example)
One for Flex (named flex-servlet.xml in the above example)
Check out this section from the Spring/BlazeDS docs for more info.

Categories