With much efforts, I was finally able to build a simple HTTPS sample server implemented in Java, as shown below. It accepts client connections and sends back a piece of text about the socket information. So I have a working server sample so far; neat and tidy. How I can make it a bi-directional connection, in such a way that client be able to send/receive information as well, in an interactive mode? How should I implement the steps for going back and forward?
Basically I want a form like this to be displayed at the browser after connecting to the server (that is easy; like now, I will send the text corresponding to the form's html code). But I need the client to send the filled-out data back to the server. Server will do some process with these raw data, and return the result back to be shown at the client.
PS: Don't forget to create a keystore certificate and provide the info below if you want to test the program.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class HttpsEchoer {
public static void main(String[] args) {
String ksName = "myks.jks";
char ksPass[] = "mypass".toCharArray();
char ctPass[] = "mypass".toCharArray();
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(ksName), ksPass);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctPass);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s
= (SSLServerSocket) ssf.createServerSocket(8888);
System.out.println("Server started:");
printServerSocketInfo(s);
// Listening to the port
int count = 0;
while (true) {
SSLSocket c = (SSLSocket) s.accept();
// Someone is calling this server
count++;
System.out.println("Connection #: "+count);
printSocketInfo(c);
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
String m = r.readLine();
// System.out.println(m);
if (m!=null) {
// We have a real data connection
w.write("HTTP/1.1 200 OK");
w.newLine();
w.write("Content-Type: text/html");
w.newLine();
w.newLine();
w.write("<html><body><pre>");
w.newLine();
w.write("Connection #: "+count);
w.newLine();
w.newLine();
w.write(m);
w.newLine();
while ((m=r.readLine())!= null) {
if (m.length()==0) break; // End of a GET call
w.write(m);
w.newLine();
}
w.write("</pre></body></html>");
w.newLine();
w.flush();
}
w.close();
r.close();
c.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Server socket class: "+s.getClass());
System.out.println(" Remote address = "
+s.getInetAddress().toString());
System.out.println(" Remote port = "
+s.getPort());
System.out.println(" Local socket address = "
+s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+s.getLocalAddress().toString());
System.out.println(" Local port = "
+s.getLocalPort());
}
private static void printServerSocketInfo(SSLServerSocket s) {
System.out.println("Server socket class: "+s.getClass());
System.out.println(" Socker address = "
+s.getInetAddress().toString());
System.out.println(" Socker port = "
+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
System.out.println(" Want client authentication = "
+s.getWantClientAuth());
System.out.println(" Use client mode = "
+s.getUseClientMode());
}
}
Your Form should also contain a <BUTTON type = "submit"...>
for sending the filled-in form, and the <FORM action="http://somesite..." method="post">
lets you determine where and how. The browser handles the client side (except for validating - you'd need some JavaScript code or equivalent).
The HTML 4 or 5 spec from http://www.w3.org/ contains lots of examples.
You may need to make the server send the response in the form of a JSON string or similar, so that the client receives that, parses the result, and displays information accordingly. This is a sample I did to receive the response of a server (in the form of a JSON string) and then prints the result (I'm too lazy to translate it to english):
package com.arielnmz;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import com.google.gson.Gson;
public class JavaHttpRequestJSON {
public static void main(String[] args) throws Exception {
while (true) {
new JavaHttpRequestJSON().testGet(new java.util.Random().nextInt());
Thread.sleep(2000);
}
}
private void testGet(int valor) throws Exception {
// Crear URL
URL url = new URL("http://localhost/http_req_test/server_script_json.php");
// Establecer conexión
URLConnection conexion = url.openConnection();
// Enviaremos información
conexion.setDoOutput(true);
// Recibiremos respuesta
conexion.setDoInput(true);
// Establecer timeouts
conexion.setConnectTimeout(5000);
conexion.setReadTimeout(5000);
// Usar caches: NO
conexion.setUseCaches(false);
conexion.setDefaultUseCaches(false);
// Le decimos al servidor qué y cómo estamos enviando
conexion.setRequestProperty("Content-Type", "application/json");
// Creamos una instancia de nuestro "codificador" JSON
String json;
Gson gson = new Gson();
// Creamos un objeto y lo codificamos como JSON
// Map<String, String> map = new HashMap<String, String>();
// map.put("valor", Integer.toString( num ) );
ObjetoEnvio objetoEnvio = new ObjetoEnvio();
objetoEnvio.setValor(valor);
json = gson.toJson(objetoEnvio);
System.out.println("Objeto en JSON: "+json+" / valor enviado "+objetoEnvio.getValor());
DataOutputStream os = new DataOutputStream(conexion.getOutputStream());
os.writeBytes(json);
os.close();
StringBuffer respuesta = new StringBuffer();
BufferedReader in = new BufferedReader(
new InputStreamReader( conexion.getInputStream() )
);
String linea;
while ((linea = in.readLine()) != null) {
respuesta.append(linea);
}
in.close();
ObjetoRespuesta respuesta_json = gson.fromJson(respuesta.toString(), ObjetoRespuesta.class);
// System.out.println(respuesta.toString());
System.out.println(respuesta_json.getMensaje());
System.out.println("Conexión finalizada");
}
private class ObjetoEnvio {
private int valor;
public void setValor(int valor) {
this.valor = valor;
}
public int getValor() {
return valor;
}
}
private class ObjetoRespuesta {
private String mensaje;
public String getMensaje() { return mensaje; }
}
}
Update :
This answer is based on this approach:
action
and method
properties as a normal HTML form would do. Eg:
<form method="POST" action="process.php">
"{ 'response' : 1 }";
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.