Setting Jackson 2 with Jersey and Tomcat - java

I have no maven project with Jersey and Tomcat. For my Json object for now i use lib:--> org.json.JSONObject. Now i want to integrate my project with Jackson but how?..
My web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>RESTful</display-name>
<servlet>
<servlet-name>restJerseyServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.fasterxml.jackson.jaxrs.json;com.rest.proof</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>restJerseyServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Example how i create a JsonObject:
JSONObject json = new JSONObject();
List<JSONObject> list = new ArrayList<JSONObject>();
Element elementsByTag = doc.getElementsByTag("table").get(1);
Elements rows = elementsByTag.getElementsByTag("tr");
for (Element row : rows) {
String ex = row.getElementsByTag("td").get(1).text();
String exx = row.getElementsByTag("td").get(2).text();
String exxx = row.getElementsByTag("td").get(3).text();
JSONObject jsonObject = new JSONObject();
jsonObject.put("Feat1", ex);
jsonObject.put("Feat2", exx);
jsonObject.put("Feat3", exxx);
list.add(jsonObject);
}
json.accumulate("Response", 200);
json.accumulate("List", list);
String result = "" + json;
return json;
i have this error when i try to consume a API:
com.fasterxml.jackson.databind.type.TypeFactory and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

I fixed with this; in the web.xml i put:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.fasterxml.jackson.jaxrs;com.rest.proof</param-value>
</init-param>
and use a ObjectNode not a JsonObject

Related

How to call property file when project is loaded through web.xml in Java?

I have made a property file and loading my database connection from that file only. What I am doing is using Servlet context, I am getting the resource
and this code I have written in my login page (login.jsp) like this
<%ServletContext servletContext = getServletContext();
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/db.properties");
if (input != null) {
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
PrintWriter writer = response.getWriter();
String text;
while ((text = reader.readLine()) != null) {
/* System.out.println(text + "\n"); */
servletContext.setAttribute(text.split("=")[0], text.split("=")[1]);
}
}
%>
So it is taking the values from my property file whenever the user is logging in, but what I want is to load my property file through web.xml so whenever the projects load or server starts it loads the connection from that property file only once not whenever the user login it calls the property file.
So here is my Java connection class where I am assigning the values from property file:
ServletContext servletContext = getServletContext();
String driverDB = servletContext.getAttribute("driver").toString();
String conn_urlDB = servletContext.getAttribute("conn_url").toString();
String userNameDB = servletContext.getAttribute("userName").toString();
String passwordDB = servletContext.getAttribute("password").toString();
DBConnection.getDataBaseProperty(driverDB, conn_urlDB, userNameDB, passwordDB);
web.xml below
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>TouchPoint</display-name>
<welcome-file-list>
<welcome-file>Login.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>LoginServlet</display-name>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.touchpoint.controller.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>com.touchpoint.controller.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
</web-app>
ServletContextListener is tha answer for you,
You can check this blog post for a better understanding
https://www.journaldev.com/1945/servletcontextlistener-servlet-listener-example
put your config strings in the web.xml file then get notified on server startup through the servletContextListener
here's an extract from that blog post:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ServletListenerExample</display-name>
<context-param>
<param-name>DBUSER</param-name>
<param-value>pankaj</param-value>
</context-param>
<context-param>
<param-name>DBPWD</param-name>
<param-value>password</param-value>
</context-param>
<context-param>
<param-name>DBURL</param-name>
<param-value>jdbc:mysql://localhost/mysql_db</param-value>
</context-param>
<listener>
<listener-class>com.journaldev.listener.AppContextListener</listener-class>
</listener>
You need to create a new class that will listen to the event of server startup:
public class AppContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext ctx = servletContextEvent.getServletContext();
String url = ctx.getInitParameter("DBURL");
String u = ctx.getInitParameter("DBUSER");
String p = ctx.getInitParameter("DBPWD");
}}

Writing to JSONobject through Restful Webservice

I am learning how to use Restful Webservice, i dont really know if my approach is good or totally wrong, so bear with me
I got a project structure, which look like this :
I want to by calling the right URL, save the string accordingly in Datum.Json
Here is my Java Class of the WebService :
package Rest;
#Path("/calendar")
public class CalendarTest {
public List<Date> dates;
#GET
#Path("/dates/get/")
#Produces(MediaType.APPLICATION_XML)
public List<Date> getUsers(){
return dates;
}
#PUT
#Path("/dates/put/{param1}+{param2}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void updateDate(#PathParam("param1") String city, #PathParam("param2") String date) throws IOException {
JSONObject obj = new JSONObject();
obj.put("City", city);
obj.put("Date", date);
try (FileWriter file = new FileWriter("/RestTest/Datum.json")) {
file.write(obj.toJSONString());
System.out.println("Successfully Copied JSON Object to File...");
System.out.println("\nJSON Object: " + obj);
}
}
}
I tested the localhost, it works fine (i can open the form.html with my localhost)
My web.xml file :
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>Rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<security-constraint>
</security-constraint>
</web-app>
But when i tried the URL http://localhost:8080/RestTest/rest/calendar/dates/put/Berlin+20-12-2019
It says the method not allowed.
Can anyone explain to me why ?
It's because when you are typing in a URL in your browser, it sends a HTTP GET request by default, so it throws an error because you do not have a GET request handler for that URL, you only have a handler for a PUT request.
You can't change the browser's default request type. What you have to do is send the request yourself using something like jQuery in your frontend / javascript.
How to send a PUT/DELETE request in jQuery?
You could use the ajax method:
$.ajax({
url: '/rest/calendar/dates/put/Berlin+20-12-2019',
type: 'PUT',
success: function(result) {
// Do something with the result
}
});

/swagger.json is working but cannot access /api-docs?

I'm trying to use API documentation using Swagger for my 'org.jboss.resteasy' Rest service. After configuration I can access 'http://localhost:8080/myrestswagger/rest/swagger.json' correctly.
it returns following:
{
"swagger": "2.0",
"info": {
"version": "3.0.0",
"title": ""
},
"host": "localhost:8080",
"basePath": "/myrestswagger/rest",
"schemes": [
"http"
]
}
But I cannot access or generate any data on 'http://localhost:8080/myrestswagger/rest/api-docs', please see my classes.
Rest Service Class :
#Path("/countryDetails")
#Api( value = "/countryDetails", description = "countryDetails" )
public class CountryController {
#Path("/countries")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#ApiOperation(value = "GetCountries", httpMethod = "GET", notes = "Get Countries against Specific URL", response = Country.class)
public List<Country> getCountries() {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
return listOfCountries;
}
#Path("/country/{id}")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Country getCountryById(#PathParam("id") int id) {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
for (Country country : listOfCountries) {
if (country.getId() == id) return country;
}
return null;
}
private List<Country> createCountryList() {
Country indiaCountry = new Country(1, "India");
Country chinaCountry = new Country(4, "China");
Country nepalCountry = new Country(3, "Nepal");
Country bhutanCountry = new Country(2, "Bhutan");
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries.add(indiaCountry);
listOfCountries.add(chinaCountry);
listOfCountries.add(nepalCountry);
listOfCountries.add(bhutanCountry);
return listOfCountries;
}
}
This is the web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>io.undertow.servlet.handlers.DefaultServlet</servlet-class>
<init-param>
<param-name>allowed-extensions</param-name>
<param-value>js, css, png, jpg, gif, html, htm, txt, pdf, jpeg, xml, zip, jar</param-value>
</init-param>
<init-param>
<param-name>disallowed-extensions</param-name>
<param-value>class, war</param-value>
</init-param>
</servlet>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<!--While using Spring integration set resteasy.scan to false or don't configure resteasy.scan parameter at all -->
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>
io.swagger.jaxrs.listing.ApiListingResource,
io.swagger.jaxrs.listing.SwaggerSerializers
</param-value>
</context-param>
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>3.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8080/myrestswagger/rest</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
This is my pom.xml dependancy (maven.project)
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.9</version>
</dependency>
You don't need both swagger.json and api-docs. Both are common names to describe the Swagger definition from your server, which can be used--as a URL--by Swagger UI to render an interactive view of the API.
From looking at the output of your swagger.json, it looks like you're not scanning your resources. Please see about adding your CountryController to the scanning path for the API.

spring com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes

I've just started my first simple spring program. I'm trying to make a Rest API using Jersey framework with spring. Its a very basic simple program to fetch list of countries. But, however it throws the error. I've gone through other solutions, none of them worked.
Web.xml
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>jersey-serlvet</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>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Error which I get is
SEVERE: StandardWrapper.Throwable
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
at com.sun.jersey.server.impl.application.RootResourceUriRules.<init>(RootResourceUriRules.java:99)
at com.sun.jersey.server.impl.application.WebApplicationImpl._initiate(WebApplicationImpl.java:1359)
at com.sun.jersey.server.impl.application.WebApplicationImpl.access$700(WebApplicationImpl.java:180)
at com.sun.jersey.server.impl.application.WebApplicationImpl$13.f(WebApplicationImpl.java:799)
at com.sun.jersey.server.impl.application.WebApplicationImpl$13.f(WebApplicationImpl.java:795)
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193)
My program
package org.arpit.java2blog.jaxrs;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.arpit.java2blog.bean.Country;
#Path("/countries")
public class CountryRestService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Country> getCountries() {
System.out.println("Getting countries");
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
return listOfCountries;
}
#GET
#Path("{id: \\d+}")
#Produces(MediaType.APPLICATION_JSON)
public Country getCountryById(#PathParam("id") int id) {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
for (Country country : listOfCountries) {
if (country.getId() == id)
return country;
}
return null;
}
// Utiliy method to create country list.
public List<Country> createCountryList() {
Country indiaCountry = new Country(1, "India");
Country chinaCountry = new Country(4, "China");
Country nepalCountry = new Country(3, "Nepal");
Country bhutanCountry = new Country(2, "Bhutan");
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries.add(indiaCountry);
listOfCountries.add(chinaCountry);
listOfCountries.add(nepalCountry);
listOfCountries.add(bhutanCountry);
return listOfCountries;
}
}
URL
http://localhost:8080/HelloWeb/rest/countries
What is missing in this one?
You don't have your Jersey servlet (ServletContainer) configured in your web.xml to pick up any resource classes. So Jersey starts up with no resources registered.
With web.xml generally the way to go, is to set an init-param to tell Jersey to scan a certain package for classes annotated with #Path and #Provider. To do that, just add the following
<servlet>
<servlet-name>jersey-serlvet</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>the.package.you.want.to.scan</param-value>
</init-param>
...
</servlet>

jaxrs - Unable to call the webservice : 404 Not Found Error

I have created a simple webservice but I am unable to call it. I get 404 Not found error.
package com.fms.mdw.rest;
#Path("/Search")
public class SearchWebService {
#POST
#Path("/searchData")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public FMSResponseInfo getSearchData(SearchDTO searchDTO) {
System.out.println("Entered the getSearchData()");
FMSResponseInfo fmsResponseInfo = new FMSResponseInfo();
List<SearchDetailsDTO> searchDetailsDtoList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
SearchDetailsDTO searchDetailsDto = new SearchDetailsDTO();
searchDetailsDto.setBarcode("barcode" + i);
searchDetailsDto.setDocNo("docNo" + i);
searchDetailsDto.setDocType("docType" + i);
searchDetailsDtoList.add(searchDetailsDto);
}
fmsResponseInfo.setStatus("200");
fmsResponseInfo.setMessage("Success");
fmsResponseInfo.setData(searchDetailsDtoList);
System.out.println("Leaving the getSearchData()");
return fmsResponseInfo;
}
}
SearchDTO has two fields searchType, searchText both of type string.So the json payload will be {"searchType":"", "searchText":""}
I have registered the webservice in the following manner in web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>LatestFMS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>LatestFMS Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.fms.mdw.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>LatestFMS Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I am able to access the webpages, but I am unable to call the webservice. I am using RESTClient to send post request. The web server is apache tomcat 7 and jersey 2.16 .
The url I am hitting is http://localhost:8082/LatestFMS/rest/Search/searchData.
I am unable to resolve the issue, please help ! ! !

Categories