I am developing a public REST API service using Netty. I am expecting some users will submit percent-encoded URL, for example with %20 for space.I need to unescape the percent-ecoded URL.
Is there a built in Netty API for this? Or is there any third party Java API for it?
I did search for a solution but could not find one.
Thanks in advance.
Netty has own class for that - io.netty.handler.codec.http.QueryStringDecoder. It is also preferred against java.net.URLDecoder as it is much faster.
Usage example:
//netty http request object
HttpRequest httpRequest = ...;
QueryStringDecoder decoder = new QueryStringDecoder(httpRequest.uri());
decoder.parameters().get("value");
Related
I want to use HttpURLConnection class in Groovy to send GET and POST (with Jsonbody) request to an api. But what can I tell you. With HttpURLConnection it is soo difficult. I do not know how to use it. There is not even a send method. It looks like when you call getResponseCode() this method sends a request. Then you have to use InputStream and for POST you even have to use OutputStream. Oh my god. For what ?? I am used to handy libraries like Jersey Client. But this HttpURLConnection is just a nightmare. I have to use it because I have jenkinsfile and in my pipeline I need to upload something. And that is possible with calling an REST Api. What do you think about HttpURLConnection ? Does someone know a good website with a GET Request and a POST Request with a body.
I think this is what you are trying to do https://www.baeldung.com/httpurlconnection-post
Making it Groovy should be pretty trivial.
If you are doing an HTTP request and you want to use vanilla Java or Groovy, then I would recommend using HttpClient and HttpRequest.Builder; it's somewhat fluid. And you supply a BodyHandler object, which can be used to get the content however you like it (String, JSON Object, whatever).
i'm creating java module to parse JSON file.
To receive file i need to send HTTP request. When I use curl my request looks like this:
curl -X GET "https://***" -H "accept: application/json" -H "apikey: ***"
How can I send the equivalent HTTP request from Java
Java has a lot of options to work with HTTP.
Option 1
Since Java 9, there is a built-in HTTP client. So You can use it to create a request without any third-party libraries.
A simple example is something like this:
HttpRequest request2 = HttpRequest.newBuilder()
.uri(new URI("some url"))
.header("someHeader", "value1")
.header("anotherHeader", "value2")
.GET()
.build();
For more examples see here
Option 2
Use third party libraries, there are many: OkHttpClient, More "old-school" Apache Http Client (HttpComponents
Option 3
If you're using spring, you might consider using Spring's WebClient. There are also wrappers in spring like RestTemplate that can come handy, but it really depends on what would you like to work with.
Many clients are coming with http connection pools that should be properly set up.
In addition, in your example, I see that you work with https - all these clients support it but it should be properly set up.
If you are using Spring then try WebClient - it is a bit harder to understand in the begging (at least harder than RestTemplate) but it pays of since RestTemplate will be discontinued.
You can find an example here
https://www.baeldung.com/spring-webclient-resttemplate
#GetMapping(value = "/tweets-non-blocking",
produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Tweet> getTweetsNonBlocking() {
log.info("Starting NON-BLOCKING Controller!");
Flux<Tweet> tweetFlux = WebClient.create()
.get()
.uri(getSlowServiceUri())
.retrieve()
.bodyToFlux(Tweet.class);
tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
log.info("Exiting NON-BLOCKING Controller!");
return tweetFlux;
}
Just be aware that this is non-blocking (e.g. asynchronous) solution so you won't get the response right away, but you subscribe to the request and then process the response when it is available. There are also blocking options in WebClient
Java has its own classes that allow you to send HTTP request. See class HttpURLConnection. However, I recommend using 3d party libraries that significantly simplify this task. Good libraries would be Apache Http client or OK Http client. I also can offer you to use another Open source library that has an HTTP client as well. It is called MgntUtils library and it is written by me. In this case your code would look something like this:
HttpClient workingClient = new HttpClient();
workingClient.setRequestProperty("accept", "application/json;charset=UTF-8");
workingClient.setRequestProperty("apikey", "***");
workingClient.setConnectionUrl("https://***");
ByteBuffer buffer =
workingClient.sendHttpRequestForBinaryResponse(HttpMethod.GET);
//or of your API returns contents of file as a string
String jsonStr = workingClient.sendHttpRequest(HttpMethod.GET);
After that, your ByteBuffer buffer or String jsonStr will hold the content of your JSON file. And now you can do whatever you need with it. Here is Javadoc for HttpClient class. The MgntUtils library can be obtained as maven artifacts here or on Github (including source code and Javadoc)
I have a few questions about a specific REST call I'm making in JAVA. I'm quite the novice, so I've cobbled this together from several sources. The call itself looks like this:
String src = AaRestCall.subTrackingNum(trackingNum);
The Rest call class looks like this:
public class AaRestCall {
public static String subTrackingNum (Sting trackingNum) throws IOException {
URL url = new URL("https://.../rest/" + trackingNum);
String query = "{'TRACKINGNUM': trackingNum}";
//make connection
URLConnection urlc = url.openConnection();
//use post mode
urlc.setDoOutput(true);
urlc.setAllowUserInteraction(false);
//send query
PrintStream ps = new PrintStream(urlc.getOutputStream());
ps.print(query);
ps.close();
//get result
BufferedReader br = new BufferedReader(new InputStreamReader(urlc
.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line=br.readLine())!=null) {
sb.append(line);
}
br.close();
return sb.toString();
}
}
Now, I have a few questions on top of the what is wrong with this in general.
1) If this rest call is returning a JSON object, is that going to get screwed up by going to a String?
2) What's the best way to parse out the JSON that is returning?
3) I'm not really certain how to format the query field. I assume that's supposed to be documented in the REST API?
Thanks in advance.
REST is a pattern applied on top of HTTP. From your questions, it seems to me that you first need to understand how HTTP (and chatty socket protocols in general) works and what the Java API offers for deal with it.
You can use whatever Json library out there to parse the HTTP response body (provided it's a 200 OK, that you need to check for, and also watch out for HTTP redirects!), but it's not how things are usually built.
If the service exposes a real RESTful interface (opposed to a simpler HTTP+JSON) you'll need to use four HTTP verbs, and URLConnection doesn't let you do so. Plus, you'll likely want to add headers for authentication, or maybe cookies (which in fact are just HTTP headers, but are still worth to be considered separately). So my suggestion is building the client-side part of the service with the HttpClient from Apache commons, or maybe some JAX-RS library with client support (for example Apache CXF). In that way you'll have full control of the communication while also getting nicer abstractions to work with, instead of consuming the InputStream provided by your URLConnection and manually serializing/deserializing parameters/responses.
Regarding the bit about how to format the query field, again you first need to grasp the basics of HTTP. Anyway, the definite answer depends on the remote service implementation, but you'll face four options:
The query string in the service URL
A form-encoded body of your HTTP request
A multipart body of your HTTP request (similar to the former, but the different MIME type is enough to give some headache) - this is often used in HTTP+JSON services that also have a website, and the same URL can be used for uploading a form that contains a file input
A service-defined (for example application/json, or application/xml) encoding for your HTTP body (again, it's really the same as the previous two points, but the different MIME encoding means that you'll have to use a different API)
Oh my. There are a couple of areas where you can improve on this code. I'm not even going to point out the errors since I'd like you to replace the HTTP calls with a HTTP client library. I'm also unaware of the spec required by your API so getting you to use the POST or GET methods properly at this level of abstraction will take more work.
1) If this rest call is returning a JSON object, is that going to get
screwed up by going to a String?
No, but marshalling that json into an obect is your job. A library like google gson can help.
2) What's the best way to parse out the JSON that is returning?
I like to use gson like I mentioned above, but you can use another marshal/unmarhal library.
3) I'm not really certain how to format the query field. I assume
that's supposed to be documented in the REST API?
Yes. Take a look at the documentation and come up with java objects that mirror the json structure. You can then parse them with the following code.
gson.fromJson(json, MyStructure.class);
Http client
Please take a look at writing your HTTP client using a library like apache HTTP client which will make your job much easier.
Testing
Since you seem to be new to this, I'd also suggest you take a look at a tool like Postman which can help you test your API calls if you suspect that the code you've written is faulty.
I think that you should use a REST client library instead of writing your own, unless it is for educational purposes - then by all means go nuts!
The REST service will respond to your call with a HTTP response, the payload may and may not be formatted as a JSON string. If it is, I suggest that you use a JSON parsing library to convert that String into a Java representation.
And yes, you will have to resort to the particular REST API:s documentation for details.
P.S. The java URL class is broken, use URI instead.
I want to use JSON in my client server application.
I need to send to the server the client name and subscribe or unsubscribe.
I'm new to java and very new to JSON.
Can I please get an example of how to do such a thing?
How can I encode the data using JSON on the client side, send it through UDP and decode it on the server side?
Thanks.
Use a third party library like XStream. It's very easy API to use.
Take mkyong's Jersey + Jackson example, or any other Jersey + Jackson example.
You'll need to familiarize yourself with with Java application server too though.
Google's GSON is very easy to use and well-documented if you are new to this stuff. That will take care of the encoding / decoding for you.
Maybe SpringMVC will help you. See this example.
I recently published a framework that may help you. Please check https://sites.google.com/site/javacornproject/corn-gate project page to get detailed information.
Below is a sample code to define and implement a service in Gate:
#GateService(name="HelloWorldService",componentTarget="net.sf.corn.gate.sample.service.HelloWorldServiceImpl")
public interface IHelloWorldService {
public String sayHelloWorld();
}
public class HelloWorldServiceImpl {
public String sayHelloWorld(){
return "Hello World";
}
}
Below are the couple of samples to access to HelloWorldService from various clients :
1- JavaScript Client AJAX Call:
var jsonrq = new JsonRpcRequest("http://localhost:8888/jsonrpc");
var response = jsonrq.send("358", "HelloWorldService", "sayHelloWorld");
2-Java Remote Client:
JsonRpcClient client= new JsonRpcClient(new URI("http://localhost/jsonrpc"));
JsonRpcResponse resp= client.callAService("HelloWorldService","sayHelloWorld");
3-REST client (Browser)
http://localhost:8888/jsonrpc/HelloWorldService/sayHelloWorld
I hope this helps.
I am trying to create a java application to read the information from ARIN using an IP Address. I see ARIN is using RESTful Web Services to get the IP information but I am not sure what I need to do to start. Some people are talking about RESTLET, other people about JAX-RS,etc. Can you please help me to take me in the right direction? Thanks!
Restlet also has a client API to interact with a remote RESTful application. See the classes Client, ClientResource for more details. For this, you need to have following jar files from Restlet distribution:
org.restlet: main Restlet jar
org.restlet.ext.xml: Restlet support of XML
org.restlet.ext.json: Restlet support of JSON. In this case, the JSON jar present in libraries folder is also required.
If I use the documentation located at this address https://www.arin.net/resources/whoisrws/whois_api.html#whoisrws. Here is a simple Restlet code you can use:
ClientResource cr = new ClientResource("http://whois.arin.net/rest/poc/KOSTE-ARIN");
Representation repr = cr.get();
// Display the XML content
System.out.println(repr.getText());
or
ClientResource cr = new ClientResource("http://whois.arin.net/rest/poc/KOSTE-ARIN.txt");
Representation repr = cr.get();
// Display the text content
System.out.println(repr.getText());
Restlet also provides some support at XML level. So you can have access to hints contained in the XML in a simple way, as described below:
ClientResource cr = new ClientResource("http://whois.arin.net/rest/poc/KOSTE-ARIN");
Representation repr = cr.get();
DomRepresentation dRepr = new DomRepresentation(repr);
Node firstNameNode = dRepr.getNode("//firstName");
Node lastNameNode = dRepr.getNode("//lastName");
System.out.println(firstNameNode.getTextContent()+" "+lastNameNode.getTextContent());
Note that you can finally handle content negotiation (conneg) since it seems supported by your REST service:
ClientResource cr = new ClientResource("http://whois.arin.net/rest/poc/KOSTE-ARIN");
Representation repr = cr.get(MediaType.APPLICATION_JSON);
In this case, your representation object contains JSON formatted data. In the same way than the DomRepresentation, there is a JsonRepresentation to inspect this representation content.
Hope it helps you.
Thierry
The problem is that you don't seem to understand very well what REST is (sorry if I'm mistaken!). Restlet and JAX-RS are both server-side related.
You probably need something like jersey-client. This is a library which helps to interact with RESTful webservices.
You could also usa plain Java libraries to make HTTP calls to the webservice. REST is tightly bound to its implementation protocol. This means that if the webservice is implemented in HTTP (most likely is) you don't need anything fancy to interact with it. Just HTTP.
I strongly encourage you to learn more about REST and HTTP itself.