I have netbean Rest Web service project with several method as follow:
#Path("restws")
public class RestWs {
#Context
private UriInfo context;
public RestWs() {
}
#GET
#Produces("application/json")
public String getJson() {
return ("{\"pesan\":\"hello\"}");
}
#PUT
#Produces("text/plain")
#Consumes("application/json")
public String putJson(String content) {
return("Content yang didapat : "+content);
}
#Path("/mahasiswaData/{id}")
#GET
#Produces("application/json")
public String getMahasiswaByID(#PathParam("id")String nim)
{
JSONObject jo = new JSONObject();
jo.put("id", nim);
jo.put("nama", "Budi");
return(jo.toJSONString());
}
#Path("/mahasiswaData/{id}")
#POST
#Consumes("text/plain")
#Produces("application/json")
public String postMahasiswaByID(#PathParam("id")String nim, String data)
{
JSONObject jo = new JSONObject();
jo.put("id", nim);
jo.put("nama", "Budi");
jo.put("message", data);
return(jo.toJSONString());
}
#Path("/mahasiswaQuery")
#GET
#Produces("application/json")
public String getMahasiswaQuery(#QueryParam("nim")String nim, #QueryParam("nama") String nama)
{
JSONObject jo = new JSONObject();
jo.put("nim", nim);
jo.put("nama", nama);
jo.put("method", "GET");
return(jo.toJSONString());
}
#Path("/mahasiswaQuery")
#POST
#Produces("application/json")
public String postMahasiswaQuery(#QueryParam("nim")String nim, #QueryParam("nama") String nama)
{
JSONObject jo = new JSONObject();
jo.put("nim", nim);
jo.put("nama", nama);
jo.put("method", "Post");
return(jo.toJSONString());
}
}
then i make new project and add rest web service client. Automatically netbeans made me a new Class:
public class NewJerseyClient {
private WebTarget webTarget;
private Client client;
private static final String BASE_URI = "http://localhost:8080/PTIRestServer/webresources";
public NewJerseyClient() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("restws");
}
public String putJson(Object requestEntity) throws ClientErrorException {
return webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_JSON), String.class);
}
public String getMahasiswaByID(String id) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("mahasiswaData/{0}", new Object[]{id}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(String.class);
}
public String postMahasiswaQuery() throws ClientErrorException {
return webTarget.path("mahasiswaQuery").request().post(null, String.class);
}
public String getMahasiswaQuery(String nim, String nama) throws ClientErrorException {
WebTarget resource = webTarget;
if (nim != null) {
resource = resource.queryParam("nim", nim);
}
if (nama != null) {
resource = resource.queryParam("nama", nama);
}
resource = resource.path("mahasiswaQuery");
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(String.class);
}
public String postMahasiswaByID(Object requestEntity, String id) throws ClientErrorException {
return webTarget.path(java.text.MessageFormat.format("mahasiswaData/{0}", new Object[]{id})).request(javax.ws.rs.core.MediaType.TEXT_PLAIN).post(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.TEXT_PLAIN), String.class);
}
public String getJson() throws ClientErrorException {
WebTarget resource = webTarget;
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(String.class);
}
public void close() {
client.close();
}
}
i can access all the get Method easily by using something like:
public static void main(String[] args) {
System.out.println(new NewJerseyClient().getMahasiswaQuery("23", "John"));
}
but when i try to access post/put method using this code:
public static void main(String[] args) {
NewJerseyClient c = new NewJerseyClient();
System.out.println(c.putJson("{\"name\":\"john\"}"));
System.out.println(c.postMahasiswaQuery());
System.out.println(c.postMahasiswaByID("plain text", "1"));
}
all of the method call give me an exception:
Exception in thread "main" javax.ws.rs.NotAcceptableException: HTTP 406 Not Acceptable
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:898)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:749)
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:88)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:650)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:421)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:646)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:402)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:305)
at client.NewJerseyClient.postMahasiswaByID(NewJerseyClient.java:68)
at client.NewJerseyClient.main(NewJerseyClient.java:84)
can anyone help me? how to access method put/post? or anyone has a sample code how to access those method?
thanks
Your Rest service code looks good. however the client code generations in Netbeans has an issue i have filed a bug in netbeans.
To make your client code success. Please change the putJson request content type from javax.ws.rs.core.MediaType.APPLICATION_JSON to javax.ws.rs.core.MediaType.TEXT_PLAIN
public String putJson(Object requestEntity) throws ClientErrorException {
return webTarget.request(javax.ws.rs.core.MediaType.TEXT_PLAIN)
.put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_JSON), String.class);
}
Similarly for postMahasiswaByID method change the request content-type javax.ws.rs.core.MediaType.TEXT_PLAIN to javax.ws.rs.core.MediaType.APPLICATION_JSON
public String postMahasiswaByID(Object requestEntity, String id) throws ClientErrorException {
return webTarget.path(java.text.MessageFormat.format("mahasiswaData/{0}", new Object[]{id}))
.request(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.post(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.TEXT_PLAIN), String.class);
}
Please let me know if it works.
Thanks
vidhya
Related
I´m trying to create a client for some Rest application. I tested the Rest application with Advanced REST client in Chrome.
I received:
{
"authorization": false,
"provider": "Provider"
}
That is okey.
but I would like obtain this in my client:
public class MainApp extends Application {
public static final String BASE_URI = "http://localhost:8000/test";
public static final String PATH_NAME= "/sytem/Consumer/r/Provider";
#Override
public void start(Stage stage) throws Exception {
}
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(BASE_URI).path(PATH_NAME);
Response response = target.request(MediaType.APPLICATION_JSON).get();
System.out.println(response);
client.close();
}
}
I only receive this in the terminal:
λ java -jar Client_consumer-1.0-SNAPSHOT.jar
org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine$1#6591f517
The class is :
#XmlRootElement
public class Auth_response implements Serializable {
private String Provider;
private boolean authorization;
public Auth_response() {
super();
}
public Auth_response(String Provider, boolean authorization) {
super();
this.Provider = Provider;
this.authorization = authorization;
}
public String getProvider() {
return Provider;
}
public boolean isAuthorization() {
return authorization;
}
public void setProvider(String Provider) {
this.Provider = Provider;
}
public void setAuthorization(boolean authorization) {
this.authorization = authorization;
}
#Override
public String toString() {
return "Auth_response{" + "Provider=" + Provider + ", authorization=" + authorization + '}';
}
}
I would like to know how to print properly the response, and how to convert to a java object again. I tried with some examples, but nothing works and I think that I need some guide.
EDIT:
I tried this for getting the object:
Auth_response r=
client.target("http://localhost:8000/test/system/Consumer/r/Provider")
.request(MediaType.APPLICATION_JSON_TYPE).
get(Auth_response.class);
System.out.println("funciona:");
System.out.println(r.getProvider());
System.out.println(r.isAuthorization());
But I obtain the next error:
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/json and type class ah.client_consumer.Auth_response
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:42)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:75)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:52)
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.aroundReadFrom(GZIPDecodingInterceptor.java:59)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:55)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:251)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:181)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:213)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:105)
... 14 more
Exception running application ah.client_consumer.MainApp
Try changing below line :
Response response = target.request(MediaType.APPLICATION_JSON).get();
System.out.println(response);
To
Response response = target.request(MediaType.APPLICATION_JSON).get(String.class);
System.out.println(response.toString());
Because you have not specified what type of response you are accepting, you are getting object as response.
SOLUTION:
Add to the code:
ResteasyProviderFactory instance=ResteasyProviderFactory.getInstance();
RegisterBuiltin.register(instance);
instance.registerProvider(ResteasyJacksonProvider.class);
The solution was finding in : Unable to find a MessageBodyReader of content-type application/json and type class java.lang.String
For example, I have some REST API testing task.
I took Unirest framework, and what I have got some JSON extractors,
protected int extractStatus (HttpResponse<JsonNode> login) {
return login.getStatus();
}
protected String extractError (HttpResponse<JsonNode> login) {
return login.getBody().getObject()
.getJSONObject("data")
.getJSONObject("error")
.toString();
}
protected String extractEmail (HttpResponse<JsonNode> login) {
return login.getBody().getObject()
.getJSONObject("data")
.getJSONObject("result")
.getJSONObject("userProfile")
.getString("registrationEmail");
}
For my simple tests:
public class LoginJSON extends Request {
#Test
public void validLoginTest() {
response = login("probe#grr.la", "9876541");
Assert.assertEquals(200, extractStatus(response));
Assert.assertNotNull("ID expected", extractId(response));
Assert.assertNotNull("Token expected", extractToken(response));
Assert.assertEquals("probe#grr.la", extractEmail(response));
Assert.assertEquals("M", extractGender(response));
Assert.assertEquals("EmailEnabled", true, extractEmailEnabled(response));
Assert.assertEquals("EmailDisabled",false, extractEmailDisabled(response));
Assert.assertEquals(2, extractRolesCount(response));
Assert.assertTrue("User role expected", extractRoleByName(response, "ROLE_USER"));
Assert.assertTrue("Admin role expected", extractRoleByName(response, "ROLE_ADMIN"));
}
Maybe there was more simpliest way?
Try Gson with Retrofit!
HttpResponse<JsonNode> jsonResponse = request.asJson();
Gson gson = new Gson();
String responseJSONString = jsonResponse.getBody().toString();
MyResponseObject myObject = gson.fromJson(responseJSONString, MyResponseObject.class);
Classes
class MyResponseObject {
#Serializable("data")
private MyDataObject myData;
#get set methods
}
class MyDataObject {
#Serializable("result")
private MyResultObject myResultObject;
#get set methods
}
class MyResultObject {
#Serializable("userProfile")
private UserProfileDao userProfileDao;
#get set methods
}
class UserProfileDao {
#Serializable("registerationEmail")
private String registerationEmail;
#get set methods
}
You could do a try catch for successful parse or failed parse.
org.jboss.resteasy.client.ClientResponseFailure: Unable to find a MessageBodyReader of content-type text/plain and type class java.lang.String
Please help to solve the issue
Provider App :
#Path("/payment")
public class PaymetResource {
Object object=null;
#Path("{type}/{gateWay}")
public Object getResource(#PathParam("type") String type){
if(type.equals("creditCard"))
object = new CreditCardPaymentResource();
if(type.equals("debitCard"))
object = new DebitCardPaymentResource();
return object;
}
}
public class CreditCardPaymentResource {
/*
#GET
#Produces(MediaType.TEXT_PLAIN)
public String processPayments(){
return "hi boss";
}*/
#GET
#Produces(MediaType.TEXT_PLAIN)
public Response processPayment(#QueryParam("cardNo") String cardNo,#PathParam("gateWay") String gateWay){
String result="processed payment with Gateway:"+gateWay+" and cardNo :"+cardNo;
return Response.status(201).entity(result).build();
//return "processed payment with Gateway:"+gateWay+" and cardNo :"+cardNo;
}
}
public class DebitCardPaymentResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String processPayment(#QueryParam("cardNo") String cardNo,#PathParam("gateWay") String gateWay,#QueryParam("pin") String pin){
return "processed payment with Gateway:"+gateWay+" and cardNo :"+cardNo+"pin No"+pin;
}
}
client app :
public class RestFirstClient{
public static void main(String[] args) {
try{
ClientRequest request = new ClientRequest("http://localhost:8081/DynamicDispatch/rest/payment/creditCard/HDFC");
request.accept("text/plain");
request.queryParameter("cardNo", "669888554");
ClientResponse<String> response = request.get(String.class);
System.out.println(response.getEntity().toString());
}catch (Exception e) {
e.printStackTrace();
}
}
}
My program is working fine when we access the service through the url. Please help me
Url :http://localhost:8081/DynamicDispatch/rest/payment/creditCard/HDFC?cardNo=99809990876
output :processed payment with Gateway:HDFC and cardNo :99809990876
The combination of content-type text/plain and type class java.lang.String is handled by the org.jboss.resteasy.plugins.providers.StringTextStar found in resteasy-core.
And the client is created like:
final ResteasyClient client =
new ResteasyClientBuilderImpl() //
.connectTimeout(10, SECONDS) //
.readTimeout(10, SECONDS) //
.connectionCheckoutTimeout(10, SECONDS) //
.register(new StringTextStar()) //
.build();
final ResteasyWebTarget target = client.target(UriBuilder.fromPath("whatever path"));
final CreditCardPaymentResource client = target.proxy(CreditCardPaymentResource.class);
i´m implementing a Restful service using Jax-RS 2.0 (Resteasy 3.0.7.Final) and share the interface between client and service.
The return value is void because ClientResponse is deprecated since RestEasy introduced JAX-RS 2.0 in version 3+.
To return the location of the new created object i inject the response, using the #Context annotation, and add the Content-Location header.
For example:
Shared Interface:
#Path("/")
#Consumes("application/xml")
#Produces("application/xml")
interface Resource {
#Path("createSomething")
void createSomething(AnyObject object);
...
}
Implementation class (The Service):
class ResourceImpl {
...
#Context org.jboss.resteasy.spi.HttpResponse response;
...
#Override
void createSomething(AnyObject object) throws AnyException {
String id = service.create(object);
response.getOutputHeaders().putSingle("Content-Location",
"/createSomething/" + id);
response.setStatus(Response.Status.CREATED.getStatusCode());
}
}
The client (build with the Resteasy Proxy Framework):
...
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(baseUrl);
Resource resource = (Resource) target.proxy(Resource.class);
resource.createSomething(anyObject);
...
How can i retrieve Header information (and others, like Atom Links) which has been injected by the service?
Is it reasonable to use client side Filters and Interceptors?
Thank You
The best solution i found was to use a Filter to process the incoming response header.
public class HeaderFilter implements ClientResponseFilter {
private Map<String, String> headers = new HashMap<>();
private List<String> headerFilter = new ArrayList<>();
public final void addHeaderFilter(final String header) {
headerFilter.add(header);
}
public final void removeHeaderFilter(final String header) {
headerFilter.remove(header);
}
public final String getHeader(final String header) {
return headers.get(header);
}
#Override
public final void filter(final ClientRequestContext requestContext,
final ClientResponseContext responseContext)
throws IOException {
headers = new HashMap<>();
for (String headerToLookFor : headerFilter) {
String header = responseContext.getHeaderString(headerToLookFor);
if (header != null) {
headers.put(headerToLookFor, header);
} else {
...
}
}
}
}
I have been creating a Rest client using jersey.
I am getting the following exception:
com.sun.jersey.api.client.ClientHandlerException: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128)
at com.sun.jersey.api.client.Client.handle(Client.java:435)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:475)
Below is my rest client:
public class RestClient {
private WebResource webResource;
private Client client;
private static String BASE_URI;
public RestClient(String url)
{
BASE_URI = url;
}
private void connect() {
com.sun.jersey.api.client.config.ClientConfig config = new com.sun.jersey.api.client.config.DefaultClientConfig();
client = Client.create(config);
client.setReadTimeout(50000);
webResource = client.resource(BASE_URI);
}
private void disconnect() {
client.destroy();
}
public TResponse topup(TRequest request) {
TResponse respone=null;
try{
System.out.println("::::::::::::::::start");
this.connect();
System.out.println("connected to base URL "+BASE_URI);
ClientResponse clientRequest = webResource.path("/topup").accept(MediaType.APPLICATION_XML).put(ClientResponse.class, request);
respone = (TopUpResponse)clientRequest.getEntity(TopUpResponse.class);
this.disconnect();
}
catch(Exception e){
e.printStackTrace();
}
System.out.println(":::::::::finish");
return respone;
}
}
Please help me to sort out this exception. Thanks in advance.
Do you have #XxmlRootElement annotation. Please read this article for more details
With jersey api all seems easy:
GET call.
Client client = Client.create();
WebResource webResource = client.resource("http://sample.com/rest_service");
MultivaluedMap queryParams = new MultivaluedMapImpl();
queryParams.add("PARAM1", param1);
queryParams.add("PARAM2", param2);
RESTResult s = webResource.queryParams(queryParams)
//Check the return type of the service
.accept(MediaType.APPLICATION_JSON)
//Put a object with XmlRootElement to map the result
.get(RESTResult .class);
println(s.status);
//Also you can return the result in a string
String s = webResource.queryParams(queryParams).get(String.class);
RESTResult code
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class RESTAuthorizationResult
{
public String status = "";
public String message = "";
}