I wish to embed a very light HTTP server in my Java Swing app which just accepts requests, performs some actions, and returns the results.
Is there a very light Java class that I can use in my app which listens on a specified port for HTTP requests and lets me handle requests?
Note, that I am not looking for a stand-alone HTTP server, just a small Java class which I can use in my app.
Since Java 6, the JDK contains a simple HTTP server implementation.
Example usage:
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class HttpServerDemo {
public static void main(String[] args) throws IOException {
InetSocketAddress addr = new InetSocketAddress(8080);
HttpServer server = HttpServer.create(addr, 0);
server.createContext("/", new MyHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
System.out.println("Server is listening on port 8080" );
}
}
class MyHandler implements HttpHandler {
public void handle(HttpExchange exchange) throws IOException {
String requestMethod = exchange.getRequestMethod();
if (requestMethod.equalsIgnoreCase("GET")) {
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/plain");
exchange.sendResponseHeaders(200, 0);
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext()) {
String key = iter.next();
List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
responseBody.close();
}
}
}
Or you can use Jetty for that purpose. It’s quite lightweight and perfectly fits this purpose.
You can use jetty as embedded server, its fairly light weight. Other option is check this out for a simple java class to handle http requests http://java.sun.com/developer/technicalArticles/Networking/Webserver/.
Other way is in Java 6 you can use com.sun.net.httpserver.HttpServer
Sun embedded web server is useful, but com.sun.net package could be dropped without notice.
A better alternative are
http://tjws.sourceforge.net/ 100kb very small and jdk 1.6-aware
http://winstone.sourceforge.net/ bigger but a good shot
http://www.eclipse.org/jetty/ Jetty, very good in developement, support SPDY and websocket
If you're not using Java 6, then I would certainly recommend Jetty. That works very well and has a decent programming interface.
You said "very light" twice, so I think JLHTTP might be a good match for you. You can embed it as a single source file or a ~35K/50K jar file, yet it supports most functionality you'd need in an HTTP server out of the box.
Disclaimer: I'm the author. But check it out for yourself and see what you think :-)
Related
I am trying to test API using Java. I am using Java 8, Apache HTTP client 4.5.3 to test it. I tried many different ways to testing using Java .net class, Apache HTTP client but every time same issue;
Exception in thread "main"
org.apache.http.conn.HttpHostConnectException: Connect to
api.github.com:443 [api.github.com/192.30.253.116,
api.github.com/192.30.253.117] failed: Connection timed out: connect
at
org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:159)
Everytime I am getting time out. But if I use same URL in Browser I am getting result.
Can someone help me to point out issue? Whether its setup issue or code issue?
Tried almost all codes available on internet. I am beginner for API testing and don't have knowledge of in depth of HTTP workflow.
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.IOException;
import java.net.*;
public class API {
public static void main(String args[]) throws IOException, URISyntaxException {
HttpUriRequest request = new HttpGet( "https://api.github.com" );
// When
HttpResponse response = HttpClientBuilder.create().build().execute( request );
System.out.println(response.getStatusLine().getStatusCode());
}
}
Using Java .net package
import java.io.IOException;
import java.net.*;
public class API {
public static void main(String args[]) throws IOException, URISyntaxException {
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json?address=chicago&sensor=false");
//URL url = uri.toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/xml");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("HTTP error code : "
+ conn.getResponseCode());
}
}
}
If the same URL works in browser then there are only three possibilities.
The URL expects headers like User-Agent. You can set request headers needed like this:
request.setHeader("User-Agent", "Mozilla");
You are in a corporate or restricted environment and need a proxy to connect to external URLs. Your browser might already be setup to use proxy server. In this case, you will need to pass proxy credentials to http client API.
Example: https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientProxyAuthentication.java
All outgoing requests are blocked in your environment by firewall or something. In this case, you will need to ask your network admin to allow network connection.
I am struggling to get a Jersey client that follows redirects, even though "I know I had this working earlier." (Haven't looked at the code in a while).
I thought had a complex case where it was failing when the redirect was from HTTP to HTTPS. But I cannot get even this simple test below to run:
package com.soliantconsulting.jira.test;
import static org.junit.Assert.*;
import com.sun.jersey.api.client.*;
import org.junit.Test;
public class JerseyClientTest {
public void test() {
Client c = Client.create();
c.setFollowRedirects( true );
WebResource r = c.resource("http://www.yahoo.com");
String response = r.get(String.class);
System.out.println( response );
}
}
When run, this code throws:
com.sun.jersey.api.client.UniformInterfaceException: GET http://www.yahoo.com returned a response status of 301 Moved Permanently
I've tried a couple different flavors of setting the redirect-follow option, so I must be doing something fundamentally wrong, I think.
Mac OS 10.9.4, JDK 1.7.0_65, Jersey 1.18.1, Eclipse Luna, Maven 3.2.3.
Is there a way to make get & put calls over HTTP in java ? I also need to automate any user inputs like a button click on the target web-page(any web-page, not just yahoo finance)
I tried using the apache commons library & couldn't quite crack it:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class Fin {
/**
* #param args
*/
public static void main(String[] args) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://finance.yahoo.com");
try {
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
} catch (Exception e) {
e.printStackTrace();
} finally {
httpget.releaseConnection();
}
}
}
I keep getting 'java.net.ConnectException: Connection refused', though i can see it in the browser.
If you really want to automate browser-based interactions, you could go further and use Watij, which runs a browser via the JVM and is driven via a browser-based API (I.e. you identify the button you want to press and it will actually do this)
Otherwise a library like the one you've identified will normally work. You have to watch out for client-side JavaScript interactions driving the requests, and configure proxies etc (I suspect this is your problem in the above)
I created a WebService client from a provided WSDL-File, using the already in the JRE bundled JAX-WS API.
I generated the proxy classes with the wsimport tool of JDK6 Update 37.
The client should be able to download large files/data, using MTOM and streaming.
I followed the instructions provided in the Metro user guide.
The proxy method I'm calling returns a DateHandler object.
package de.christopherhuebner.webservicetest.client;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import javax.activation.DataHandler;
import javax.xml.namespace.QName;
import de.christopherhuebner.webservicetest.ImageServer;
import de.christopherhuebner.webservicetest.ImageServerService;
public class ImageServiceClient {
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:8080/ImageWebService?wsdl");
QName qname = new QName("http://webservicetest.christopherhuebner.de/", "ImageServerService");
ImageServerService is = new ImageServerService(url, qname);
MTOMFeature mtom = new MTOMFeature();
StreamingAttachmentFeature stf = new StreamingAttachmentFeature(null, true, 4000000L);
ImageServer port = is.getImageServerPort(mtom, stf);
DataHandler dh = port.getImage();
System.out.println("Java-Version: " + System.getProperty("java.version"));
System.out.println("DataHandler: " + dh.getClass());
System.out.println("DataSource: " + dh.getDataSource().getClass());
OutputStream out = new FileOutputStream("test.jpg");
dh.writeTo(out);
out.close();
}
}
When running this code with JRE6, the following output is printed to the console:
Java-Version: 1.6.0_37
DataHandler: class javax.activation.DataHandler
DataSource: class com.sun.istack.internal.ByteArrayDataSource
Unfortunately there is no streaming possible, as the ByteArrayDataSource is filled in the clients memory which causes an OutOfMemoryException when receiving data larger than the max heap size. When I dare to cast this DataHandler to a StreamingDataHandler as suggested in the already mentioned user guide, a ClassCastException is thrown.
When running the client with JRE7, everything is fine, as described in the user guide:
Java-Version: 1.7.0_10
DataHandler: class com.sun.xml.internal.ws.encoding.MIMEPartStreamingDataHandler
DataSource: class com.sun.xml.internal.ws.encoding.MIMEPartStreamingDataHandler$StreamingDataSource
Is there any possibility to get a StreamingDataHandler back, when using JRE6?
Or am I really forced to use a newer JAX-WS RI version (Metro, which seems to be included in the JRE) via the -Djava.endorsed.dirs=path_to_newer_jaxws_libs mechanism?
When are the temp files, which are generated during streaming (MIMExxxxx.tmp, see StreamingAttachmentFeature for configuration), deleted?
A simple question, but could someone provide sample code as to how would someone call a web service from within the JBoss Seam framework, and process the results?
I need to be able to integrate with a search platform being provided by a private vendor who is exposing his functionality as a web service. So, I'm just looking for some guidance as to what the code for calling a given web service would look like.
(Any sample web service can be chosen as an example.)
There's roughly a gajillion HTTP client libraries (Restlet is quite a bit more than that, but I already had that code snippet for something else), but they should all provide support for sending GET requests. Here's a rather less featureful snippet that uses HttpClient from Apache Commons:
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod("http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=restbook&query=HttpClient");
client.executeMethod(method);
import org.restlet.Client;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.resource.DomRepresentation;
import org.w3c.dom.Node;
/**
* Uses YAHOO!'s RESTful web service with XML.
*/
public class YahooSearch {
private static final String BASE_URI = "http://api.search.yahoo.com/WebSearchService/V1/webSearch";
public static void main(final String[] args) {
if (1 != args.length) {
System.err.println("You need to pass a search term!");
} else {
final String term = Reference.encode(args[0]);
final String uri = BASE_URI + "?appid=restbook&query=" + term;
final Response response = new Client(Protocol.HTTP).get(uri);
final DomRepresentation document = response.getEntityAsDom();
document.setNamespaceAware(true);
document.putNamespace("y", "urn:yahoo:srch");
final String expr = "/y:ResultSet/y:Result/y:Title/text()";
for (final Node node : document.getNodes(expr)) {
System.out.println(node.getTextContent());
}
}
}
}
This code uses Restlet to make a request to Yahoo's RESTful search service. Obviously, the details of the web service you are using will dictate what your client for it looks like.
final Response response = new Client(Protocol.HTTP).get(uri);
So, if I understand this correctly, the above line is where the actual call to the web service is being made, with the response being converted to an appropriate format and manipulated after this line.
Assuming I were not using Restlet, how would this line differ?
(Of course, the actual processing code would be significantly different as well, so that's a given.)