Angular 2 Jax-RS with GET faster than POST - java

I have a REST application using Jax-RS and Angular 2, Apache 8.5 and Postgres database using Hibernate.
The problem is when I save a new object, the GET from my list runs before the POST run completely. Here are the codes.
tabela-servicos.component.ts
import { Component, OnInit } from '#angular/core';
import { Servico } from '../servico';
import { CrudServicosService } from '../crud-servicos.service';
#Component({
selector: 'app-tabela-servicos',
templateUrl: './tabela-servicos.component.html',
styleUrls: ['./tabela-servicos.component.css']
})
export class TabelaServicosComponent implements OnInit {
titulo = "Tabela de Serviços";
servicos: Servico[] = [];
constructor(private servicoService: CrudServicosService) {
}
ngOnInit() {
console.log('called ngOnInit')
this.servicoService.getServicos()
.subscribe(s => {
console.log(s);
this.servicos = s;
}, erro => console.log(erro));
}
remover(servico: Servico){
this.servicoService.removerServico(servico)
.subscribe(() => {
let novosServicos = this.servicos.slice(0);
let indice = novosServicos.indexOf(servico);
novosServicos.splice(indice, 1);
this.servicos = novosServicos;
});
}
}
form-servicos.component.ts
import { Component, OnInit } from '#angular/core';
import { CrudServicosService } from '../../app/crud-servicos.service';
import { Servico } from '../../app/servico';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-form-servicos',
templateUrl: './form-servicos.component.html',
styleUrls: ['./form-servicos.component.css']
})
export class FormServicosComponent implements OnInit {
titulo = "Cadastro de Servicos";
servico: Servico;
codigo;
constructor(private servicoService: CrudServicosService,
private router: Router,
private rota:ActivatedRoute) { }
ngOnInit() {
this.codigo = this.rota.snapshot.params['cod'];
if(isNaN(this.codigo)){
this.servico = new Servico();
} else {
this.servico = Object.assign({},
this.servicoService.getServicoPorCodigo(this.codigo));
}
}
salvarServico(){
if(isNaN(this.codigo)){
this.servicoService.adicionarServico(this.servico)
} else {
this.servicoService.atualizaServico(this.codigo, this.servico);
}
// console.log("waiting 2 seconds to return page list...");
// setTimeout(()=>{
this.router.navigate(['/lista']);
// },2000);
}
cancelar(){
this.router.navigate(['/lista']);
}
}
ServicoResource.java
package resource;
import java.util.ArrayList;
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.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import dao.ServicoDAO;
import model.Servico;
#Path("servico")
public class ServicoResource {
private static ServicoDAO servicoDao = new ServicoDAO();
#GET
#Path("servicos")
#Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
public Response test() {
List<Servico> serv = servicoDao.getList();
System.out.println("GET Objectos from Jax-RS");
System.out.println("");
return Response.ok(serv).build();
}
#Path("servicos/delete/{id}")
#DELETE
public Response removeProduto(#PathParam("id") long id){
System.out.println("DELETE Object ID: " + id + " Jax-RS ");
System.out.println("");
servicoDao.remover(id);
return Response.ok().build();
}
#POST//consume o objeto enviado pro back-end
#Consumes(MediaType.APPLICATION_JSON)
public Response adiciona(String conteudo){
Gson gson = new Gson();
Servico s = gson.fromJson(conteudo, Servico.class);
servicoDao.salvar(s);
System.out.println("POST Object Jax-RS");
System.out.println("");
return Response.status(200).build();
}
}
When I reload the list page, after the saved object, it appears.
When I use the code below in the form-servicos.component.ts class, it works, but I know this is a bad practice.
console.log ("waiting 2 seconds to return page list ...");
setTimeout (() => {
This.router.navigate (['/ list']);
}, 2000);
Does anyone know how to resolve this problem from the list being requested before the object is persisted ???

(Posted on behalf of the OP).
This was solved.
adicionarServico(servico: Servico){
console.log("Called persist POST "+JSON.stringify(servico));
return this.http.post(this.baseUrl + '/servico', JSON.stringify(servico), {headers: this.headers});
}
I changed my crud-service.ts to return an Observable < Responde > and using it in:
salvarServico(){
this.servicoService.adicionarServico(this.servico)
.subscribe(() => {
console.log("Saved Success");
this.router.navigate(['/lista']);
});
}

Related

Basic Pact/Junit5 Test Setup fails. No method annotated with #Pact was found for provider error

I tried to follow the documentation on Pact.io to write a simple integration test.
Unfortunately i get an exception as follows:
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [au.com.dius.pact.consumer.MockServer mockServer] in method [public void com.example.demo.integration.pact.PactTest.setUp(au.com.dius.pact.consumer.MockServer)]: No method annotated with #Pact was found on test class PactTest for provider 'node_server'
It says that I don't have any method annotated with #Pact. However I do have a method, which is annotated with #Pact.
I tried to run the test manually and with 'mvn test' as well.
The application in general is providing some Rest Controllers, which should be tested.
Following is all I have implemented regarding my Pact Test Implementation. Am I missing something?
package com.example.demo.integration.pact;
import au.com.dius.pact.consumer.MockServer;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
import au.com.dius.pact.consumer.junit5.PactTestFor;
import au.com.dius.pact.core.model.RequestResponsePact;
import au.com.dius.pact.core.model.annotations.Pact;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Request;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
#ExtendWith(PactConsumerTestExt.class)
#PactTestFor(providerName = PactTest.PACT_PROVIDER_NAME)
public class PactTest {
public static final String PACT_PROVIDER_NAME = "node_server";
public static final String PACT_CONSUMER_NAME = "spring_application";
#BeforeEach
public void setUp(MockServer mockServer) {
System.out.println("Mockserver check called");
Assertions.assertTrue(mockServer != null);
}
#Pact(provider = PACT_PROVIDER_NAME, consumer = PACT_CONSUMER_NAME)
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.uponReceiving("notes")
.path("/notes")
.method("GET")
.willRespondWith()
.matchHeader("Content-Type","application/json")
.status(200)
.body(
getJsonArrayOfNotes(2).toString())
.toPact();
}
#Test
#PactTestFor(pactMethod = "notes")
void test(MockServer mockServer) throws IOException {
HttpResponse httpResponse = Request.Get(mockServer.getUrl() + "/notes").execute().returnResponse();
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
assertEquals(getJsonArrayOfNotes(2).toString(),httpResponse.getEntity().getContent().toString());
}
private JSONArray getJsonArrayOfNotes(int size) {
var responseJsonObject = new JSONArray();
for (int i = 0; i < size; i++) {
var note = new JSONObject();
try {
note.put("title", String.format("Title %s", i + 1));
note.put("content", String.format("Some Note Content of Note %s", i + 1));
} catch (Exception exception) {
}
responseJsonObject.put(note);
}
return responseJsonObject;
}
}
Seems like the method name with the #Pact annotation must be the same as the pactMethod in the #PactTestFor annotation...
In my case I had to write following:
#Test
#PactTestFor(pactMethod = "getNotes")
void test(MockServer mockServer) throws IOException {
HttpResponse httpResponse = Request.Get(mockServer.getUrl() + "/notes").execute().returnResponse();
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
assertEquals(getJsonArrayOfNotes(2).toString(),httpResponse.getEntity().getContent().toString());
}
#Pact(provider = PACT_PROVIDER_NAME, consumer = PACT_CONSUMER_NAME)
public RequestResponsePact getNotes(PactDslWithProvider builder) {
return builder
.uponReceiving("notes")
.path("/notes")
.method("GET")
.willRespondWith()
.matchHeader("Content-Type","application/json")
.status(200)
.body(
getJsonArrayOfNotes(2).toString())
.toPact();
}

How to parse REST API STREAM

I am sending a get request to the server and server returns the following two responses. These responses are received as the event occurs on servers in streams (like id1,id2,id3,id4.....and so on) not in one shot.
Now, I need to take these response one by one and parse it and then save it the objects for further use.
How do i achieve this java 8 and spring MVC?
id: 1
data: {"event_type":"ABC","business_call_type":"XYZ","agent_number":"nnn","call_recording":null,"number":"0000","uuid":"a","call_direction":"Outbound","caller":"+100000000000","customer_number":"+100000000000","version":"1.0","k_number":"+917303454203","type":"AGENT_CALL","unique_id":"0","call_solution":"xx","FreeSWITCH_IPv4":"11111","Event_Date_Local":"2020-03-28 11:46:47"}
id: 2
data: {"event_type":"AGENT_ANSWER","business_call_type":"Outbound","agent_number":"+1111111111","call_recording":null,"number":"+22222222","uuid":"bbbbbbbbbbbbbb","call_direction":"Outbound","caller":"+100000000000","customer_number":"+100000000000","version":"1.0","k_number":"+1111111111","type":"AGENT_ANSWER","unique_id":"bbbbbbbbbb","call_solution":"xx","FreeSWITCH_IPv4":"0.0.0.0","Event_Date_Local":"2020-03-28 11:47:00"}
below is the code used foe above json parsing.
import java.util.HashMap;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.context.request.async.DeferredResult;
import com.psg.async_tasks.controller;
import com.psg.dao.CtiIntegrationdao;
// #Controller
#Service
public class ListningService {
private static final Logger logger = Logger.getLogger(ListningService.class.getName());
#Autowired
CtiIntegrationdao daoCtiInt;
//#RequestMapping({"list"})
#PostConstruct
public void ListningReponse() {
HashMap<String,String> results=daoCtiInt.getKnolarity_Config();
String endpoint;
endpoint=results.get("30");
endpoint=endpoint.replace("<<AUTH>>",results.get("26"));
logger.info(endpoint);
logger.info("============================================================================================#postconstruct=========");
AsyncRestTemplate asyncrestTemplate = new AsyncRestTemplate();
try {
final DeferredResult<String> result = new DeferredResult<>();
ListenableFuture<ResponseEntity<String>> futureEntity = asyncrestTemplate.getForEntity(endpoint, String.class);
logger.info("IN TRY");
logger.info(futureEntity.toString());
futureEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
#Override
public void onSuccess(ResponseEntity<String> result) {
String[] idno = result.getBody().split("\\R", 3);
System.out.println("==================="+idno[0]);
String responseBody =result.getBody().replaceAll("id: (\\d+)","").replace("data: ","");;
logger.info("-----responsebody-----"+responseBody);
logger.info("-----responsebody-----"+result.getBody());
// logger.info("-----responsebody-----"+result.getBody().getAgent_number());
// logger.info("-----responsebody-----"+result.getBody().getBusiness_call_type());
// logger.info("-----responsebody-----"+result.getBody().getCall_duration());
// logger.info("-----responsebody-----"+result.getBody().getCall_recording());
// logger.info("-----responsebody-----"+result.getBody().getCall_solution());
// logger.info("-----responsebody-----"+result.getBody().getCall_Type());
// logger.info("-----responsebody-----"+result.getBody().getDestination());
}
#Override
public void onFailure(Throwable ex) {
result.setErrorResult(ex.getMessage());
logger.info("------------Failure Block"+result.toString());
}
});
}catch(HttpClientErrorException ex) {
logger.info(ex.getMessage());
}catch(Exception ex) {
ex.printStackTrace();
}
}
}

Use Actors to send data to Akka websockets

I am using Akka websockets to push data to some client.
This is what I have done so far:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeUnit;
import akka.NotUsed;
import akka.actor.ActorSystem;
import akka.http.javadsl.ConnectHttp;
import akka.http.javadsl.Http;
import akka.http.javadsl.ServerBinding;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.HttpResponse;
import akka.http.javadsl.model.ws.Message;
import akka.http.javadsl.model.ws.WebSocket;
import akka.japi.Function;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.javadsl.Flow;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
public class Server {
public static HttpResponse handleRequest(HttpRequest request) {
System.out.println("Handling request to " + request.getUri());
if (request.getUri().path().equals("/greeter")) {
final Flow<Message, Message, NotUsed> greeterFlow = greeterHello();
return WebSocket.handleWebSocketRequestWith(request, greeterFlow);
} else {
return HttpResponse.create().withStatus(404);
}
}
public static void main(String[] args) throws Exception {
ActorSystem system = ActorSystem.create();
try {
final Materializer materializer = ActorMaterializer.create(system);
final Function<HttpRequest, HttpResponse> handler = request -> handleRequest(request);
CompletionStage<ServerBinding> serverBindingFuture = Http.get(system).bindAndHandleSync(handler,
ConnectHttp.toHost("localhost", 8080), materializer);
// will throw if binding fails
serverBindingFuture.toCompletableFuture().get(1, TimeUnit.SECONDS);
System.out.println("Press ENTER to stop.");
new BufferedReader(new InputStreamReader(System.in)).readLine();
} finally {
system.terminate();
}
}
public static Flow<Message, Message, NotUsed> greeterHello() {
return Flow.fromSinkAndSource(Sink.ignore(),
Source.single(new akka.http.scaladsl.model.ws.TextMessage.Strict("Hello!")));
}
}
At the client side, I am successfully receiving a 'Hello!' message.
However, now I want to send data dynamically (preferably from an Actor), something like this:
import akka.actor.ActorRef;
import akka.actor.UntypedActor;
public class PushActor extends UntypedActor {
#Override
public void onReceive(Object message) {
if (message instanceof String) {
String statusChangeMessage = (String) message;
// How to push this message to a socket ??
} else {
System.out.println(String.format("'%s':\nReceived unknown message '%s'!", selfActorPath, message));
}
}
}
I am unable to find any example regarding this online.
The following is the software stack being used:
Java 1.8
akka-http 10.0.10
One - not necessarily very elegant - way of doing this is to use Source.actorRef and send the materialized actor somewhere (maybe a router actor?) depending on your requirements.
public static Flow<Message, Message, NotUsed> greeterHello() {
return Flow.fromSinkAndSourceMat(Sink.ignore(),
Source.actorRef(100, OverflowStrategy.fail()),
Keep.right()).mapMaterializedValue( /* send your actorRef to a router? */);
}
Whoever receives the actorRefs of the connected clients must be responsible for routing messages to them.

Subject no longer authenticated in session after logging in with Shiro

I am using Guice + Jersey + Shiro to login via a REST API and then use the same HTTP session under which I logged in to and have my permissions work for that resource.
Below is my code.
Firstly, my servlet configuration:-
public class ServletConfiguration extends GuiceServletContextListener
{
private ServletContext mServletContext;
#Override
public void contextInitialized(ServletContextEvent inEvent)
{
mServletContext = inEvent.getServletContext();
super.contextInitialized(inEvent);
}
#Override
protected Injector getInjector()
{
mServletContext.addListener(new au.com.tt.agora.configuration.CbiCleanupHttpSessionListener());
return Guice.createInjector(new JerseyServletModule() {
#Override
protected void configureServlets()
{
install(new TTShiroWebModule(mServletContext));
install(new ShiroAopModule());
filter("/*").through(GuiceShiroFilter.class);
bind(ShiroLoginResource.class);
bind(ShiroResource.class);
filter("/*").through(GuiceContainer.class);
}
});
}
}
Now, this is my test realm:-
package au.com.tt.agora.configuration.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class TestRealm extends AuthorizingRealm
{
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken inToken) throws AuthenticationException
{
UsernamePasswordToken upToken = (UsernamePasswordToken) inToken;
if (upToken.getUsername().equals("Kamal") || upToken.getUsername().equals("NotKamal"))
return new SimpleAuthenticationInfo(upToken.getUsername(), upToken.getPassword(), getName());
return null;
}
#Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection inPrincipals)
{
String username = (String) inPrincipals.fromRealm(getName()).iterator().next();
SimpleAuthorizationInfo authzInfo = new SimpleAuthorizationInfo();
if (username.equals("Kamal"))
{
authzInfo.addStringPermission("PRODMA:READ:AU");
authzInfo.addStringPermission("PRODMA:WRITE:KB");
authzInfo.addStringPermission("SUPPMA:READ:KB");
}
else
{
authzInfo.addStringPermission("PRODMA:READ:AU");
authzInfo.addStringPermission("PRODMA:WRITE:KB");
}
return authzInfo;
}
}
This is the web module
package au.com.tt.agora.configuration.shiro;
import javax.servlet.ServletContext;
import org.apache.shiro.guice.web.ShiroWebModule;
public class TTShiroWebModule extends ShiroWebModule
{
public TTShiroWebModule(ServletContext inServletContext)
{
super(inServletContext);
}
#SuppressWarnings("unchecked")
#Override
protected void configureShiroWeb()
{
bindRealm().to(TestRealm.class);
addFilterChain("**/shiroResource/*", ANON);
}
}
Here is the resource I use to login:-
package au.com.tt.agora.configuration.jaxrs.resources;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import com.google.inject.Inject;
import au.com.tt.agora.configuration.option.ClientProvider;
import au.com.tt.agora.configuration.option.ConfigurationProvider;
import au.com.tt.agora.login.web.request.LoginRequest;
import au.com.tt.agora.login.web.request.LoginResponse;
import au.com.tt.agora.login.web.service.LoginHandler;
import au.com.tt.calypso.cbi.CalypsoException;
#Path("/{client}/shiroLogin")
public class ShiroLoginResource
{
private static final String ROUTING_TOKEN_HEADER = "proxy-jroute";
#POST
#Path("/standard")
#Produces(MediaType.TEXT_PLAIN)
#Consumes(MediaType.APPLICATION_JSON)
public String login(#Context HttpServletRequest inServletRequest) throws CalypsoException
{
Subject subject = SecurityUtils.getSubject();
subject.login(new UsernamePasswordToken("Kamal", "Password", false));
return getSessionIdWithRouting(inServletRequest);
}
private String getSessionIdWithRouting(HttpServletRequest inRequest)
{
String sessionId = inRequest.getSession().getId();
return(sessionId);
}
}
And here is the resource I am calling:-
package au.com.tt.agora.configuration.jaxrs.resources;
import javax.servlet.http.HttpSession;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
#Path("/{client}/shiroResource")
public class ShiroResource
{
private static final Logger LOG = LoggerFactory.getLogger(ShiroResource.class);
#Inject
public ShiroResource()
{
}
#POST
#Path("requiresProdma.do")
#Produces(MediaType.TEXT_PLAIN)
#RequiresPermissions({ "PRODMA:*:*" })
public String prodmaRequired()
{
return "Success";
}
#POST
#Path("requiresSuppma.do")
#Produces(MediaType.TEXT_PLAIN)
#RequiresPermissions({ "SUPPMA:*:*" })
public String suppmaRequired()
{
Subject subject = SecurityUtils.getSubject();
subject.getPrincipal();
return "Success";
}
}
If I put a breakpoint into suppmaRequired and call this resource, I can see that subject is not authenticated.
My understanding on how Shiro works is obviously faulty, but I don't know what I am not doing. Can anyone point me in the right direction?
Not sure if it makes a difference, but I am using URL rewriting to access the web session.
Basically, I am using the fetch API to test this. Here is an example:-
fetch("http://localhost/app/tt/shiroLogin/standard", {
method: "POST",
headers: {
"Content-Type" : "application/json"
} ,
body: '{"username":"myName","password":"myPassword"}'
})
.then(function(res) {
return res.text();
})
.then(function(sessionId) {
return fetch("http://localhost/app/tt/shiroResource/requiresSuppma.do;JSESSIONID=" + sessionId,
{
method: "POST"
});
})
.then(function(res) {
return res.text();
})
.then(function(res) {
console.log(res);
});
I am also deploying to glassfish.
OK, this was not a Shiro problem in the end. I was using two different sessions going from the ShiroLoginResource to ShiroResource.
I forgot that you actually needed to inject with a session level object in Guice to force Guice to create a session. Stupid me.
Once I injected a session scoped dependency into ShiroLoginResource and interacted with it, then everything just worked.
I will keep this question open because it gives some useful code snippets.

How to integrate with ASP.net Web API application from Java Client

I am trying to consume JSON from my ASP.net Web API application, from a Java client.
I able to easily do this from a .net client. But cannot figure out a way to do it in JAVA. I have scoured the web to no avail.
Any help would be sincerely appreciated.
Here is the controller code.
public class OrderController : ApiController
{
private SuperiorPizzaEntities1 db = new SuperiorPizzaEntities1();
// GET api/Order
public IEnumerable<Order> GetOrders()
{
List<Order> orders = db.Orders.ToList();
return orders;
}
... More controller methods here.
}
/// Orders Class
public partial class Order
{
public Order()
{
this.OrderDetails = new HashSet<OrderDetail>();
}
public int OrderID { get; set; }
public int UserID { get; set; }
public System.DateTime CreatedDate { get; set; }
public virtual UserAddress UserAddress { get; set; }
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
Java Client Code follows.
This is the code I have written to try to decipher the JSON
/// Java code
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.Object;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.json.*;
import javax.json.stream.*;
import javax.json.stream.JsonParser.Event;
public class JSONReader {
public static void main(String[] args) {
try {
URL url = new URL("http://MyServer/WebAPIs/api/Order");
InputStream is = url.openStream();
JsonParser parser = Json.createParser(is);
{
while (parser.hasNext())
{
Event e = parser.next();
if (e == Event.KEY_NAME)
{
switch (parser.getString())
{
case "name":
parser.next();
System.out.print(parser.getString());
System.out.print(": ");
break;
case "message":
parser.next();
System.out.println(parser.getString());
System.out.println("---------");
break;
default:
//parser.next();
System.out.println(parser.getString());
System.out.println("---------");
break;
}
}
}
}
}
catch(IOException exc)
{
System.out.println("There was an error creating the HTTP Call: " + exc.toString());
}
}
Thanks again
I would try to get away from the manual parsing of the Json. I use the Google GSON library to serialize JSON into an actual java class instance. Here is a quick example.
// standard import statements
// ....
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class MyItem
{
public String name;
public String message;
}
/// ... calling code
Gson gson = new Gson();
// hypotehtical call to HTTP endpoint for JSON
String fullJSONListText = getFullJSONFromURL();
// JSON array example e.g: [{name: 'test', message: 'hello}, ...]
Type listType = new TypeToken<List<MyItem>>(){}.getType();
List<MyItem> results = gson.fromJson(fullJSONListText, listType);
//JSON object example
// hypotehtical call to another HTTP endpoint again
String fullJSONObjectText = getFullJSONObjectFromURL();
Type objType = new TypeToken<MyItem>(){}.getType();
MyItem result = gson.fromJson(fullJSONObjectText, objType);

Categories

Resources