REST API is unable to work in JSON format - java

I am new to developing REST API with Java. I made a very simple one using the mkyong tutorials, where it only says "hello". I am using Apache Tomcat.
Now I am trying to develop a one where it will return the JSON objects. I am attempting the example here - http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/. Some of the code are changed (ex: package name).Below is my code.
Track.java
package com.tutorialspoint;
/**
*
* #author Yohan
*/
public class Track {
String title;
String singer;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
#Override
public String toString() {
return "Track [title=" + title + ", singer=" + singer + "]";
}
}
JsonService.java
package com.tutorialspoint;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*
* #author Yohan
*/
#Path("/json/metallica")
public class JsonService {
#GET
#Path("/get")
#Produces(MediaType.APPLICATION_JSON)
public Track getTrackInJSON() {
Track track = new Track();
track.setTitle("Enter Sandman");
track.setSinger("Metallica");
return track;
}
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
public Response createTrackInJSON(Track track) {
String result = "Track saved : " + track;
return Response.status(201).entity(result).build();
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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>Restful Web Application</display-name>
<servlet>
<servlet-name>NewServlet</servlet-name>
<servlet-class>NewServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Jersey RESTful 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.tutorialspoint</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>NewServlet</servlet-name>
<url-pattern>/NewServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Jersey RESTful Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
My application is not a marven project. So the added libraries are below.
I tested the application with the below URL.
http://localhost:8080/RESTFUL_API_SAMPLE/rest/json/metallica/get
All I got is the below page
Any idea about why I am not getting the expected result?

Currently you don't have any JSON/POJO support. The jersey-json jar and the POJOMappingFeature configuration in your web.xml is for Jersey 1.x, which won't work for Jersey 2.x. For all the jars you need for Jersey 2.x support, see this answer.

Related

a strange name next to the webapp name shown in eclipse server tab

My pom is as follow:
<modelVersion>4.0.0</modelVersion>
<groupId>net.codejava</groupId>
<artifactId>EhrmsWs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
and in eclipse,web project settings, context root is
EhrmsWs
but when I add this webapp to wildfly runtime, there is a name
MyWebsite-0.0.1-SNAPSHOT.war
where does this name come from and what does it represents?
my context root is still
http://127.0.0.1:8080/EhrmsWs
?
the application is a simple web service example, I access using postman, request is
http://127.0.0.1:8080/EhrmsWs/rest/products/
but it returns 404 - Not Found, why?
the web.xml setting is as follow:
<?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>EhrmsWs</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>net.codejava.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
the service class is as follow:
package net.codejava.ws;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/products")
public class ProductResource {
private ProductDAO dao = ProductDAO.getInstance();
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response list() {
List<Product> listProducts = dao.listAll();
if (listProducts.isEmpty()) {
return Response.noContent().build();
}
return Response.ok(listProducts).build();
}
//.....
}
[Edit on 20220816]
Now the request
http://localhost:8080/EhrmsWs/rest/products
can pass to resource ProductResource.java, but I write a similar resource TrainingHist.java with similar method as follow:
package net.codejava.ws;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/trainingHist")
public class TrainingHistResource {
private TrainingHistDAO dao = TrainingHistDAO.getInstance();
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response list() {
List<TrainingHist> listTrainingHists = dao.listAll();
if (listTrainingHists.isEmpty()) {
return Response.noContent().build();
}
return Response.ok(listTrainingHists).build();
}
}
then I send the get request
http://localhost:8080/EhrmsWs/rest/trainingHist
but it returns 404 not found, why?

JAX-RS web service using jquery facing error 404

This is my web.xml.
<?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>NewsPortal</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.newsportal</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
There may be something wrong with web.xml but I am not sure.
Here is my web service .
package com.newsportal;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import com.newsportal.utility.ErrorReporting;
#Path("/Authentication")
public class AuthenticationResource {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.APPLICATION_JSON)
#Path("/login")
public Response login(#FormParam("emailOrPhone") String emailOrPhone,#FormParam("password") String password){
String response ="";
try{
}catch(Exception ex){
ErrorReporting.webServiceError(ex);
}
return Response.ok(response)
.header("Access-Control-Allow-Origin", "*")
.build();
}
}
This is JAX-RS i think here most of the code looks fine .
Here is my jquery I am trying to invoke this login method
var Index = function() {
var handleIndexLoad = function() {
// no authentication at load
}
var handlelogin = function() {
var emailOrPhone='admin#nextolive.com';
var password ='12345';
$.ajax({
method : "POST",
url : "Authentication/login/",
data :'emailOrPhone='+ emailOrPhone +'&password='+password,
}).done(function(response) {
console.log(response);
});
}
return {
// main function to initiate the module
init : function() {
handleIndexLoad();
handlelogin();
}
};
}();
This is index.js file . I think here also things are fine .
To be honest I am new to Java so , i am not really sure if I am following
the right pattern .
Please tell me what i need to do fix it .

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>

Add new endpoint to existing App Engine backend server in Android Studio

I have an App Engine backend with Google Cloud Messaging setup in my local Android Studio.
It has the original endpoints as follows:
Messaging Endpoint
Registration Endpoint
I have created a new Java file and added a new class called UserRegistration as follows:
package com.xxxxx.gcmbackend;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Named;
import static com.xxxxxx.gcmbackend.OfyService.ofy;
#Api(
name = "register",
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "gcmbackend.xxxxx.com",
ownerName = "gcmbackend.xxxxx.com",
packagePath=""
)
)
public class UserRegistrationEndpoint {
private static final Logger log = Logger.getLogger(RegistrationEndpoint.class.getName());
#ApiMethod(name = "register")
public void registerDevice(#Named("regId") String regId, #Named("username") String username, #Named("phone") String phone) {
if(findRecord(regId) != null) {
log.info("Device " + regId + " already registered, skipping register");
return;
}
RegistrationRecord record = new RegistrationRecord();
record.setRegId(regId);
record.setUsername(username);
record.setPhone(phone);
ofy().save().entity(record).now();
}
private RegistrationRecord findRecord(String regId) {
return ofy().load().type(RegistrationRecord.class).filter("regId", regId).first().now();
}
}
However, when deployed, I don't see this endpoint in the API explorer. How do I add a new working endpoint to an App Engine backend with Google Cloud Messaging?
Going through existing code structure, I found out that every new API must be added to the web.xml file. I added my new endpoint as:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern></url-pattern>
</filter-mapping>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.xxxxx.gcmbackend.RegistrationEndpoint, com.xxxxx.gcmbackend.MessagingEndpoint, com.xxxxx.gcmbackend.UserRegistrationEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: JSON support in Java REST Webservices with Jersey

Okay, this question has probably been asked before, but on all sites I've looked the explanation on "how to do this" tells me I'm doing it completely right.
I know I'm not, as I get a 500 server error on my localhost tomcat and I get the following error in my server logs:
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class com.myapp.domain.Location, and Java type class com.myapp.domain.Location, and MIME media type application/json was not found
So, what I'm trying to do is to develop a RESTful web service with Jersey (in Java). Everything is going fine, except for the fact that I want to return JSON. I can't find what I'm doing different from these people:
How to send response as JSON in Jersey Rest
http://www.jasonwhaley.com/blog/2011/01/18/multiple-content-types-in-jax-rs/
https://github.com/jasonray/jersey-starterkit/wiki/Serializing-a-POJO-to-xml-or-json-using-JAXB
https://github.com/jasonray/jersey-starterkit/wiki/Serializing-a-POJO-to-json-using-built-in-jersey-support
http://www.vogella.com/tutorials/REST/article.html
My POJO (Location) looks like this:
package com.myapp.domain;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement()
public class Location {
private int id;
private double longtitude;
private double latitude;
public Location() {
new Location(-1, -1, -1);
}
public Location(double longtitude, double latitude) {
new Location(-1, longtitude, latitude);
}
public Location(int id, double longtitude, double latitude) {
this.id = id;
this.longtitude = longtitude;
this.latitude = latitude;
}
public void setID(int id) {
this.id = id;
}
public void setLongtitude(double longtitude) {
this.longtitude = longtitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public int getID() {
return this.id;
}
public double getLongtitude() {
return this.longtitude;
}
public double getLatitude() {
return this.latitude;
}
}
My resource looks like this:
package com.myapp.MyAPP;
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 com.myapp.domain.Location;
#Path("Locations")
public class LocationInfo {
#GET
#Path("/get/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Location getLocation(#PathParam("id") int id) {
Location loc = new Location(3, 4.007391, 51.00237);
return loc;
}
}
And this is my web.xml:
<?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_2_5.xsd"
id="WebApp_ID"
version="2.5">
<display-name>MyAPP</display-name>
<servlet>
<servlet-name>MyAPP REST Service</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.myapp.MyAPP</param-value>
</init-param>
<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>MyAPP REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I've got these libraries included: asm-3.1.jar, jersey-client-1.17.1.jar, jersey-core-1.17.1.jar, jersey-json-1.17.1.jar, jersey-server-1.17.1.jar, jersey-servlet-1.17.jar, jsr11-api-1.1.1.jar
The one who sees what I'm not seeing gets a beer. Or at least my eternal gratitude, cause I've been looking at this for way too long and I still can't see it.
Okay, so I turned out orid had the right answer: I simply needed to add some extra libraries!
I probably overlooked it or most tutorials probably suppose you add all the libraries you download with jersey straight away...
So this fixed the problem: adding
jackson-core-asl-1.9.2.jar
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jackson-xc-1.9.2.jar
Thanks again to orid, you just saved my weekend.

Categories