Building a Rest Server - java

I've learned how to send and handle Rest API requests, so am reasonably comfortable with how an outside user would submit requests to an API through methods such as opening a connection to the API, setting a request method and processing returned messages.
However the time has come to create my own Rest Web Service, and I'm a bit stuck as I'm not entirely familiar with just how the server will handle the communication.
I can set up a connection just fine to allow for communication, but I'm not particularly comfortable with the specifics of a connection.
Below is the method where I initialise the server, which will then wait until something connects and have a brief conversation until the client disconnects.
public void Initialise(){
try {
ServerSocket s = new ServerSocket(21); //TODO: Change port?
while(true){
Socket incoming = s.accept();
Runnable r = new ConnectionManager(incoming);
Thread t = new Thread(r);
t.start();
}
}
catch(IOException e){
e.printStackTrace();
}
}
And the class handling the connection.
public class ConnectionManager implements Runnable{
private Socket incoming;
public ConnectionManager(Socket i){
this.incoming = i;
}
#Override
public void run() {
try{
try{
//Initialise IOStreams
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true);
out.println("TODO: Change this message. Press Q to quit.");
boolean done = false;
while (!done && in.hasNextLine()){
String line = in.nextLine();
out.println("Echo: " +line);
if (line.trim().equals("Q")){
done = true;
}
}
}
finally{
incoming.close();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
What I'm not sure of how to do, is how I start building an application that listens for Rest requests, and then processes them accordingly. I feel confident that upon examining the connection, I'd be able to engineer functionality to process the API request, however I do not know how to view the specifics of a Rest request sent by a user.
For example, if a user were to send a request, such as
GET exampleAPI/endpoint?params
How do I examine the request, and then subsequently process it accordingly?
For example, on the client side when you initiate the request, an approach such as the use of HttpURLConnection would allow you to follow the process of
HttpURLConnection c = (HttpURLConnection) targetURL.openConnection();
c.setRequestMethod("GET");
Which would allow you to submit a Get request to the target URI.
Looking through the Java Documentation for Socket, I don't quite know how I can view incoming requests and active connections.
Am I missing something, or just doing things completely wrong?

As I mentioned in my comments, you can use Jersey/Spring/etc.. for this rather than you rewriting the logic for the whole server and handling multiple threads, etc..
Also, you should know that there is a JDK API called JAX-RS (specification plus implementation) for the same. you can look here
You can look here for Spring REST Controller or here for Jersey.
I recommend you go through JDK JAX-RS API first, then you may have a look at Spring and Jersey.
There are other vendors implementing JAX-RS, which you may be interested in, you can look here for comparison for JAX-RS implementations.
P.S.: You should also know that Spring does not compliant to JAX-RS API, rather they have got their own API.

Related

How to connect to a broker API using sockets and Java?

I've been trying to connect to the XTB API and I can't seem to make it work.
I have zero experience with sockets and I'm learning on the go. I'm trying to send the JSON object and I'm expecting some kind of response either a success message or an error but I don't get anything. I don't even know if I'm doing it right.
public static void main(String[] args) {
String host = "xapi.xtb.com";
int port = 5112;
Socket s;
try {
JSONObject main = new JSONObject();
JSONObject user = new JSONObject();
main.put("command", "login");
user.put("userId", "MY_ID");
user.put("password", "MY_PSSWD");
main.put("arguments", user);
s = new Socket(host, port);
SocketAddress a;
a = new InetSocketAddress("xapi.xtb.com", 5112);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
out.write(main.toString());
String response = in.readLine();
System.out.println(response);
in.close();
out.close();
} catch (IOException ex) {
ex.printStackTrace(System.out);
}
}
I only managed to get their WebSocket endpoints to work. That, in addition to the fact that their entire API documentation contains WebSocket commands only, makes me think they expect users to connect that way.
I can't help you with Java, but the algorithm is as follows:
1. Define connection
Get a WebSocket client library / package. Usually first thing you do is to instantiate an object using the wss://... address as parameter. Don't issue the connect command at this stage.
2. Define event handlers
Most WebSocket clients dispatch events which you need to handle in your code.
First event will typically be 'open' and it will be fired once the connection is established. Every message coming from server will fire a 'message' event. You need to write handlers for the 'onOpen' and 'onMessage' events (however the naming convention may be) which will execute your code's logic.
Typically there will be a 'send' command in your WebSocket package that you can use to send messages to the server. Use the command described in the documentation as payload of the send command:
// pseudocode
ws.send({
"command":"login",
"arguments": {
"userId":"1000",
"password":"PASSWORD"
}
})
3. Connect
Once the event handlers are defined, you can issue the 'connect' command.
Good luck with your trading. Hope it helps.
maybe im very, very, very too late but... I have been playing with your example.
You are getting null, because the connection is plain http.
To fix it, you need to change:
import java.net.Socket;
to
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
And then, when creating the socket...
instead of
Socket s
s = new Socket(host, port);
You must put this:
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket s = (SSLSocket) factory.createSocket(host, port);
Also, after out.write.... add
out.flush();
And you are done
Why? in the xtb api docs they said this:
All servers use SSL connection.
And after messing a bit with wireshark, I found that the JSON was sent in plain text...
You may have already found it before, because this question is old, but it remains here in case someone else has the problem

Mock XMPP Server with Mina works only part of the time

I've created a mock XMPP server that processes PLAIN encryption stanzas. I'm able to use Pidgin and go through the entire session creation, to the point where Pidgin thinks the user is on an actually XMPP server and is sending regular pings.
However, it seems like not all messages are processed correctly and when I do get a successful login, it was just luck. I'm talking, maybe 1/10th of the time I actually get connected. The other times it seems like Pidgin missed a message or I dumped messages to fast on the transport.
If I enable Pidgin's XMPP Console plugin, the first connection is ALWAYS successful, but a second user fails to make it through, typically dying when Pidgin requests Service Discovery.
My Mina code is something like this:
try
{
int PORT = 20600;
IoAcceptor acceptor = null;
acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addFirst("codec", new ProtocolCodecFilter( new ProtocolCodecFactoryImpl()));
acceptor.getFilterChain().addLast("executor", new ExecutorFilter(IoEventType.MESSAGE_RECEIVED));
acceptor.setHandler( new SimpleServerHandler());
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind( new InetSocketAddress(PORT));
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
}
and the SimpleServerHandler is responsible for message/stanza processing and session creation. The messageReceived function looks like:
#Override
public void messageReceived(IoSession session, Object msg) throws Exception
{
String str = msg.toString();
System.out.println("MESSAGE: " + str);
process(session, str);
}
and finally, process is in charge of parsing the message out, and writing the response. I do use sychonized on my write:
public void sessionWrite(IoSession session, String buf)
{
synchronized(session)
{
WriteFuture future = session.write(buf);
}
}
I have omitted my processing code for brevity, but it simply looks for certain pieces of data, crafts a response and calls sessionWrite(...)
My question is, will this pattern work? And if not, should I consider shoving received messages in a Queue and simply processing the Queue from say a Timer?
It turns out, Pidgin would send two IQ stanzas, but I wasn't handling them correctly. My decoder now determines the end of a stanza and only writes a stanza to the buffer I read from.
Works like a dream now!

Java - Server that services each client in a seperate thread?

I am trying to setup my MessageServer class so that it services each client in a separate request (you'll see below that it's pretty linear right now)
How should I go about it?
import java.net.*;
import java.io.*;
public class MessageServer {
public static final int PORT = 6100;
public static void main(String[] args) {
Socket client = null;
ServerSocket sock = null;
BufferedReader reader = null;
try {
sock = new ServerSocket(PORT);
// now listen for connections
while (true) {
client = sock.accept();
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
Message message = new MessageImpl(reader.readLine());
// set the appropriate character counts
message.setCounts();
// now serialize the object and write it to the socket
ObjectOutputStream soos = new ObjectOutputStream(client.getOutputStream());
soos.writeObject(message);
System.out.println("wrote message to the socket");
client.close();
}
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
Sorry, but your question doesn't make much sense.
If we are using the term "request" in the normal way, a client sends a request to the server and the server processes each request. It simply makes no sense for a server to not service the requests separately (in some sense).
Perhaps you are asking something different. (Do you mean, "service each client request in a separate thread"?) Whatever you mean, please review your terminology.
Given that you are talking about executing requests in different threads, then using the ExecutorService API is a good choice. Use an implementation class that allows you to put an upper bound on the number of worker threads. If you don't, you open yourself up for problems where overload results in the allocation of large numbers of threads, which only makes the server slower. (Besides, creating new threads is not cheap. It pays to recycle them.)
You should also consider configuring your executor so that it doesn't have a request queue. You want the executor service to block the thread that is trying to submit the job if there isn't a worker available. Let the operating system queue incoming connections / requests at the ServerSocket level. If you queue requests internally, you can run into the situation where you are wasting time by processing requests that the client-side has already timed out / abandoned.

Java Multithreaded Web Server - Not recieving multiple GET requests

I have the starts of a very basic multi-hreaded web server, it can recieve all GET requests as long as they come one at a time.
However, when multiple GET requests come in at the same time, sometimes they all are recieved, and other times, some are missing.
I tested this by creating a html page with multiple image tags pointing to my webserver and opening the page in firefox. I always use shift+refresh.
Here is my code, I must be doing something fundamentally wrong.
public final class WebServer
{
public static void main(String argv[]) throws Exception
{
int port = 6789;
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(port);
}
catch(IOException e)
{
System.err.println("Could not listen on port: " + port);
System.exit(1);
}
while(true)
{
try
{
Socket clientSocket = serverSocket.accept();
new Thread(new ServerThread(clientSocket)).start();
}
catch(IOException e)
{
}
}
}
}
public class ServerThread implements Runnable
{
static Socket clientSocket = null;
public ServerThread(Socket clientSocket)
{
this.clientSocket = clientSocket;
}
public void run()
{
String headerline = null;
DataOutputStream out = null;
BufferedReader in = null;
int i;
try
{
out = new DataOutputStream(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while((headerline = in.readLine()).length() != 0)
{
System.out.println(headerline);
}
}
catch(Exception e)
{
}
}
First, #skaffman's comment is spot on. You should not catch-and-ignore exceptions like your code is currently doing. In general, it is a terrible practice. In this case, you could well be throwing away the evidence that would tell you what the real problem is.
Second, I think you might be suffering from a misapprehension of what a server is capable of. No matter how you implement it, a server can only handle a certain number of requests per second. If you throw more requests at it than that, some have to be dropped.
What I suspect is happening is that you are sending too many requests in a short period of time, and overwhelming the operating system's request buffer.
When your code binds to a server socket, the operating system sets up a request queue to hold incoming requests on the bound IP address/port. This queue has a finite size, and if the queue is full when a new request comes, the operating system will drop requests. This means that if your application is not able to accept requests fast enough, some will be dropped.
What can you do about it?
There is an overload of ServerSocket.bind(...) that allows you to specify the backlog of requests to be held in the OS-level queue. You could use this ... or use a larger backlog.
You could change your main loop to pull requests from the queue faster. One issue with your current code is that you are creating a new Thread for each request. Thread creation is expensive, and you can reduce the cost by using a thread pool to recycle threads used for previous requests.
CAVEATS
You need to be a bit careful. It is highly likely that you can modify your application to accept (not drop) more requests in the short term. But in the long term, you should only accept requests as fast as you can actually process them. If it accepts them faster than you can process them, a number of bad things can happen:
You will use a lot of memory with all of the threads trying to process requests. This will increase CPU overheads in various ways.
You may increase contention for internal Java data structures, databases and so on, tending to reduce throughput.
You will increase the time taken to process and reply to individual GET requests. If the delay is too long, the client may timeout the request ... and send it again. If this happens, the work done by the server will be wasted.
To defend yourself against this, it is actually best to NOT eagerly accept as many requests as you can. Instead, use a bounded thread pool, and tune the pool size (etc) to optimize the throughput rate while keeping the time to process individual requests within reasonable limits.
I actually discovered the problem was this:
static Socket clientSocket = null;
Once I removed the static, it works perfectly now.

Java websocket host?

I'm trying some multiplayer game ideas out at the moment and am trying to create a Java application to serve a web browser based multiplayer game.
My development environment is Eclipse on the main machine, and notepad + Google Chrome on this laptop.
I'm creating the websocket using javascript at the client end, and using the java.net.Socket at the server end.
I've managed to get a connection acknowledged at both ends, but can't seem to send or recieve any data between them without the client closing the connection (doesn't even error; just seems to freak out at something and call socket.close).
Does anyone have any ideas?
Here's some code:
Client:
<script type="text/javascript">
var socket;
function init() {
socket = new WebSocket("ws://192.168.0.3:10000");
socket.onopen = function() { alert('OPEN: ' + socket.readyState); }
socket.onmessage = function (msg) { alert('DATA: ' + msg.data); }
socket.onerror = function (msg) { alert('DATA: ' + msg.data); }
socket.onclose = function () { alert('CLOSED: ' + socket.readyState); }
}
function onClick() {
socket.send("YAY!");
}
</script>
Server:
public static void main(String args[])
{
System.out.printLn("Websocket server test");
ServerSocket connectSocket = null;
try
{
Socket clientSocket;
connectSocket = new ServerSocket(10000);
System.out.printLn("Waiting for connection...");
clientSocket = connectSocket.accept();
System.out.printLn("Got one!");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
for(int i=0;i<100;i++) //Shit but easy
{
String data = in.readLine();
System.out.printLn("Got data: " + data);
out.printLn("YAY!");
}
}
catch (IOException e)
{
System.out.printLn("You fail: " + e.getMessage());
}
System.out.printLn("Finished!");
}
Rather than going the painful way of implementing the spec in Java, I'd suggest that you use an existing solution like jWebSocket.
Also if you don't mind leaving Java land, I'd also suggest that you take a look at Node.js for your Server.
Doing both Server and Client in JavaScript will save you lots of time and lots of Code, especially since JSON just doesn't fit that well into static land. Also creating multiplayer servers in Node.js is trivial, since the event based, single threaded model fits the whole thing pretty well.
More information on WebSocket can be found in the FAQ. In case you want to get started with Node.js take a look at the TagWiki.
shameless plug follows
For two multiplayer games that were written using Node.js take a look at my GitHub page.
Try this lib - https://github.com/mrniko/netty-socketio
Based on high performance socket lib Netty. It supports latest protocol of Socket.IO server. Several transports including websocket.
On web side use Socket.IO client javascript lib:
<script type="text/javascript">
var socket = io.connect('http://localhost:81', {
'transports' : [ 'websocket' ],
'reconnection delay' : 2000,
'force new connection' : true
});
socket.on('message', function(data) {
// here is your handler on messages from server
});
// send object to server
var obj = ...
socket.json.send(obj);
</script>
I would suggest our high level solution: Bristleback Server. It contains both server and client, you can choose from several existing low level WebSocket engines (like Jetty, Netty or Tomcat), developing with Bristleback is extremally fast and easy. However, it is still Beta and we are working hard to release a final 1.0.0 version. If you use Maven, we have provided an archetype with ready to use web application.
I am one of the co-creators of Bristleback Server.
As no one yet really answered your question: the reason it does not work, is because you are not implementing the websocket specification. It takes of lot more work to setup a proper websocket connection than just opening a socket, as the websocket connection setup starts with a HTTP upgrade request. Your client is closing the connection, because it does not receive a positive answer on the upgrade request to start with.
I can't help you with sockets, but can i suggest you to use RMI technology? I'm trying to make a multiplayer rpg in java, and i'm using remote method invocation between server and client (it is possible also call-back the client from the server). It's really easy use it, but it uses TCP instead of UDP. In LAN experience there is no lag, on internet I have not tried yet. However, if your game tolerates just a bit retard between request and response, there is no problem.
This is the link of my project, Client and Server classes may be useful for you.

Categories

Resources