I'm using Ember for front-end and Java for back-end. On typing localhost:8080, I need to show the Ember homepage index.html. Previously, I used Node.js and the below line did the trick
res.sendfile('./public/index.html');
Now on shifting to Java, I'm unable to achieve the same result. I tried the below code.
public static void main(String[] args) throws Exception
{
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/", new HHandler());
server.createContext("/getbookarray", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class HHandler implements HttpHandler
{
#Override
public void handle(HttpExchange t) throws IOException
{
File file = new File("..\\public\\index.html");
String response = FileUtils.readFileToString(file);
String encoding = "UTF-8";
t.getResponseHeaders().set("Content-Type", "text/html; charset=" + encoding);
t.getResponseHeaders().set("Accept-Ranges", "bytes");
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes("UTF-8"));
os.close();
}
}
But, unfortunately I'm getting the below error on trying to load the home page.
"Uncaught SyntaxError: Unexpected token <"
The same Ember application when processed using Node.js works fine. I guess I'm not sending the HTTP response properly. Any help is appreciated.
Maybe you have an issue with the path of your file. Also notice that the readFileToString is deprecated.
Here is a working server that will send your index.html to your frontend.
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
public class myServer {
public static void main(String[] args) throws Exception {
System.out.println("server ...");
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/", new HHandler());
//server.createContext("/getbookarray", new HHandler());
//server.setExecutor(null); // creates a default executor
server.start();
//server.getExecutor();
}
static class HHandler implements HttpHandler {
#Override
public void handle(HttpExchange t) throws IOException {
Headers h = t.getResponseHeaders();
String line;
String resp = "";
try {
File newFile = new File("src/index.html");
System.out.println("*****lecture du fichier*****");
System.out.println("nom du fichier: " + newFile.getName());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(newFile)));
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
resp += line;
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
h.add("Content-Type", "application/json");
t.sendResponseHeaders(200, resp.length());
OutputStream os = t.getResponseBody();
os.write(resp.getBytes());
os.close();
}
}
}
You can use the lightweight server nanoHttpd. With the following code you can send your index.html file to your frontend also.
import fi.iki.elonen.NanoHTTPD;
import java.io.*;
public class App extends NanoHTTPD {
public App() throws IOException {
super(8080);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
System.out.println("\nRunning! Point your browsers to http://localhost:8080/ \n");
}
public static void main(String[] args) {
try {
new App();
} catch (IOException ioe) {
System.err.println("Couldn't start server:\n" + ioe);
}
}
#Override
public Response serve(NanoHTTPD.IHTTPSession session) {
File newFile = new File("src/index.html");
System.out.println("*****lecture du fichier*****");
System.out.println("nom du fichier: " + newFile.getName());
String line;
String reponse = "";
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(newFile)));
while ((line = bufferedReader.readLine()) != null){
reponse += line;
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return newFixedLengthResponse(reponse);
}
}
Related
I want to encrypt using RSA_OAEP_SHA256 on the JavaScript side.
I am using the third party library asmcrypto.js :
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/asmCrypto/0.22.0/asmcrypto.js"></script>
<script>
var encrypted = asmCrypto.RSA_OAEP_SHA256.encrypt(stringToBeEncrypted, pubkey, "");
</script>
getting error: Uncaught TypeError: Cannot read property 'encrypt' of undefined.
Does anybody know the solution or any example that would help?
So finally I found the solution, I am sharing it here so that it will be helpful to someone.
I changed the library and used jsencrypt.min.js JSEncrypt
It is an updated one that supports OAEP padding.
JavaScript Code :
<script type="text/javascript" src="/RSO/includes/jsencrypt.min.js"></script>
function get(tmpSubmit)
{
<%
String key = BouncyCastlePemUtils.readPublicKey();
System.out.println("readPublicKey: " + key);
%>
alert('<%=key %>');
var publicKey = '<%=key %>';
var password = "Dhiraj is the author";
var RSAEncrypt = new JSEncrypt();
RSAEncrypt.setPublicKey(publicKey);
var encryptedPass = RSAEncrypt.encrypt(password, true);
document.write("encryptedPass: "+encryptedPass)
}
Generate Public and Private Key using openssl, please check the link below for commands.
openssl commands
Java Class to encrypt and decrypt data:
package com.demo.rsa;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.demo.util.CommonProperties;
public class PEMDemo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public String encrypt(String plainText, RSAPublicKey publicKey) throws Exception {
Cipher cipher = getCipher();
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return DatatypeConverter.printBase64Binary(encryptedText);
}
public String decrypt(String cipherText, RSAPrivateKey privateKey) throws Exception {
byte[] cipherBytes;
cipherBytes = DatatypeConverter.parseBase64Binary(cipherText);
Cipher cipher = getCipher();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedText = cipher.doFinal(cipherBytes);
return new String(decryptedText, StandardCharsets.UTF_8);
}
private Cipher getCipher() throws Exception {
Security.addProvider(new BouncyCastleProvider());
return Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", new BouncyCastleProvider());
}
public static RSAPublicKey getPublicKey(){
RSAPublicKey publicKey = null;
try {
File publicKeyFile = new File(CommonProperties.propBag.getProperty("RSA_CONFIG_PATH")+"public_key.pem");
publicKey = BouncyCastlePemUtils.readX509PublicKey(publicKeyFile);
} catch (InvalidKeySpecException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return publicKey;
}
public static RSAPrivateKey getPrivateKey(){
RSAPrivateKey privateKey = null;
try {
File privateKeyFile = new File(CommonProperties.propBag.getProperty("RSA_CONFIG_PATH")+"private_key.pem");
privateKey = BouncyCastlePemUtils.readPKCS8PrivateKey(privateKeyFile);
} catch (InvalidKeySpecException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return privateKey;
}
public static void main(String[] args){
PEMDemo rsaEncriptDecrypt = new PEMDemo();
String encrypted;
try {
encrypted = rsaEncriptDecrypt.encrypt("This is plain text.", getPublicKey());
System.out.println("encrypted: " + encrypted);
// JS Encrypted cipher text
encrypted = "voxgNKCtKy6wGL/g9oi/jUqwm4lnT+Ais4ZaJ5OwJ4gozjTHl3L7yabB04tyV9UmuxfGb6EywZvrpuZRIKtqWPzO+UgW0A+5g9nPjXtDPI0qMzuv7i1E7WVjM4isJBwOC4yPdttXi4h/vbzOaR5J5r8mbyHdnxkqtuDn3o5jXOM=";
String decrypted = rsaEncriptDecrypt.decrypt(encrypted, getPrivateKey());
System.out.println("decrypted: " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Utility class to read Public and Private Key from .PEM file
package com.demo.rsa;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import com.demo.util.CommonProperties;
public class BouncyCastlePemUtils {
public static RSAPublicKey readX509PublicKey(File file) throws InvalidKeySpecException, IOException, NoSuchAlgorithmException {
KeyFactory factory = KeyFactory.getInstance("RSA");
try (FileReader keyReader = new FileReader(file);
PemReader pemReader = new PemReader(keyReader)) {
PemObject pemObject = pemReader.readPemObject();
byte[] content = pemObject.getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return (RSAPublicKey) factory.generatePublic(pubKeySpec);
}
}
public static RSAPrivateKey readPKCS8PrivateKey(File file) throws InvalidKeySpecException, IOException, NoSuchAlgorithmException {
KeyFactory factory = KeyFactory.getInstance("RSA");
try (FileReader keyReader = new FileReader(file);
PemReader pemReader = new PemReader(keyReader)) {
PemObject pemObject = pemReader.readPemObject();
byte[] content = pemObject.getContent();
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
return (RSAPrivateKey) factory.generatePrivate(privKeySpec);
}
}
public static String readPublicKey() throws IOException {
File publicKeyFile = new File(CommonProperties.propBag.getProperty("RSA_CONFIG_PATH")+"public_key.pem");
StringBuilder st = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(publicKeyFile))){
String s = st.toString();
while ((s = br.readLine()) != null)
st.append(s);
}
return st.toString();
}
}
Maven Dependancy:
6. Maven Dependancy:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
I've started this multi chat thread alert system and I've successfully gotten multiple clients on the server, but when broadcasting the message to everyone, it only interacts with the initial client sending the message and the sever only, the other client does not receive the message.
Here are the codes I'm working with
Client 1
package popup;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ClientJFrame extends javax.swing.JFrame {
static Socket s;
static DataInputStream din;
static DataOutputStream dout;
public ClientJFrame() {
super("Client 1");
initComponents();
}
private void alertButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
String msgout = "Alert client 1\n";
dout.writeUTF(msgout);
} catch (Exception e) {
}
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ClientJFrame().setVisible(true);
}
});
try {
s = new Socket("127.0.0.1", 111);
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
String msgin = "";
while (true) {
msgin = din.readUTF();
messageArea.append(msgin);
JOptionPane.showMessageDialog(null, "BITCH WE ON FIRE");
s.close();
System.exit(0);
}
} catch (Exception e) {
}
}
// Variables declaration - do not modify
private javax.swing.JButton alertButton;
private javax.swing.JScrollPane jScrollPane1;
private static javax.swing.JTextArea messageArea;
// End of variables declaration
}
Server
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class TestJFrame extends javax.swing.JFrame {
static ServerSocket listener;
static Socket s;
private static final int PORT = 111;
public TestJFrame() {
super("Main");
initComponents();
}
public static class Handler extends Thread {
private final Socket socket;
private DataInputStream in;
private DataOutputStream out;
public Handler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
in = new DataInputStream(socket.getInputStream());
messageArea.append("in\n");
out = new DataOutputStream(socket.getOutputStream());
messageArea.append("Out\n");
} catch (IOException e) {
}
while (true) {
try {
String input = in.readUTF();
messageArea.append(input);
out.writeUTF("We on Fire!!!\n");
} catch (IOException ex) {
Logger.getLogger(TestJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String args[]) throws IOException, InterruptedException {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new TestJFrame().setVisible(false);
createAndShowGUI();
}
});
listener = new ServerSocket(PORT);
try {
while (true) {
new Handler(listener.accept()).start();
}
} finally {
listener.close();
}
}
// Variables declaration - do not modify
private javax.swing.JButton alertButton;
private javax.swing.JScrollPane jScrollPane1;
private static javax.swing.JTextArea messageArea;
// End of variables declaration
}
When a client connects to the server, add him to a list, so you always know who's connected. The same goes for when he disconnects.
When a client sends a message, process it however you want, then iterate over the list of connected clients and send them the message.
Take a look at the observer pattern, I think it will help for your project.
When I try to connect node.js from java socket.io client I'm getting this error:
engine intercepting request for path "/socket.io/" +0ms
engine handling "GET" http request "/socket.io/1/" +0ms
engine unknown transport "undefined" +0ms
Meantime, when I try from a javascript client, works fine:
engine intercepting request for path "/socket.io/" +0ms
engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=1494940689150-0&b64=1" +0ms
engine handshaking client "3EFWO3PTlnvZksM8AAAA" +15ms
My Java client code:
import io.socket.IOAcknowledge;
import io.socket.IOCallback;
import io.socket.SocketIO;
import io.socket.SocketIOException;
import org.json.JSONException;
import org.json.JSONObject;
public class BasicExample implements IOCallback {
private SocketIO socket;
public static void main(String[] args) {
try {
new BasicExample();
} catch (Exception e) {
e.printStackTrace();
}
}
public BasicExample() throws Exception {
socket = new SocketIO();
socket.connect("http://localhost:9990", this);
socket.send("Hello Server");
// Sends a JSON object to the server.
socket.send(new JSONObject().put("key", "value").put("key2","another value"));
// Emits an event to the server.
socket.emit("event", "argument1", "argument2", 13.37);
}
#Override
public void onMessage(JSONObject json, IOAcknowledge ack) {
try {
System.out.println("Server said:" + json.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onMessage(String data, IOAcknowledge ack) {
System.out.println("Server said: " + data);
}
#Override
public void onError(SocketIOException socketIOException) {
System.out.println("an Error occured");
socketIOException.printStackTrace();
}
#Override
public void onDisconnect() {
System.out.println("Connection terminated.");
}
#Override
public void onConnect() {
System.out.println("Connection established");
}
#Override
public void on(String event, IOAcknowledge ack, Object... args) {
System.out.println("Server triggered event '" + event + "'");
}
}
In Java, I'm using socketio.jar downloaded from here http://www.java2s.com/Code/Jar/s/Downloadsocketiojar.htm, wich seems was compiled from here https://github.com/Gottox/socket.io-java-client
In node.js server I'm user socket.io#1.0.6 version.
Please, can someone help me?
This client looks to be outdated about 5 years. It seems this is a newer one: https://github.com/socketio/socket.io-client-java
I'm trying to do a connection between a server in Java and a JavaScript client but I'm getting this error on client side:
WebSocket connection to 'ws://127.0.0.1:4444/' failed: Connection closed before receiving a handshake response
It maybe stays on OPENNING state because the connection.onopen function is never called. The console.log('Connected!') isn't being called.
Could someone let me know what is going wrong here?
Server
import java.io.IOException;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(4444)) {
GameProtocol gp = new GameProtocol();
ServerThread player= new ServerThread(serverSocket.accept(), gp);
player.start();
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
}
}
ServerThread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket socket = null;
private GameProtocol gp;
public ServerThread(Socket socket, GameProtocol gp) {
super("ServerThread");
this.socket = socket;
this.gp = gp;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
while ((inputLine = in.readLine()) != null) {
outputLine = gp.processInput(inputLine);
System.out.println(outputLine);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
GameProtocol
public class GameProtocol {
public String processInput(String theInput) {
String theOutput = null;
theOutput = theInput;
return theOutput;
}
}
Client
var connection = new WebSocket('ws://127.0.0.1:4444');
connection.onopen = function () {
console.log('Connected!');
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
To start with, both your code looks identical the Java and JavaScript one. Both work for what they are design to, but the facts is that you are trying to connect a WebSocket client to a socket server.
As I know they are two different things regarding this answer.
I have never tried it your way. That said if I have a network application that use socket than it would be pure client/server socket, and if it was a web application than I would use WebSocket on both side as well.
So far so good..
To make this work, this answer suggests to use any available WebSocket on server side and your problem is solved.
I am using WebSocket for Java and here is a sample implementation that I have tested with your client code and it works, both on client and server side.
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
public class WebsocketServer extends WebSocketServer {
private static int TCP_PORT = 4444;
private Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
System.out.println("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
System.out.println("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Message from client: " + message);
for (WebSocket sock : conns) {
sock.send(message);
}
}
#Override
public void onError(WebSocket conn, Exception ex) {
//ex.printStackTrace();
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
System.out.println("ERROR from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
}
On your main method just:
new WebsocketServer().start();
You might need to manipulate your code to fit it with this implementation, but that should be part of the job.
Here is the test output with 2 tests:
New connection from 127.0.0.1
Message from client: Ping
Closed connection to 127.0.0.1
New connection from 127.0.0.1
Message from client: Ping
here is WebSocket maven configuration, otherwise download the JAR file/s manually and import it in your IDE/development environment:
<!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket -->
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.0</version>
</dependency>
Link to WebSocket.
I am working in a project. In which i am trying to get username from session created using the following code:-
GetCurrentUserInfo.java
package servlet;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Vector;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetCurrentUserInfo extends HttpServlet
{
ServletContext contx = null;
public void init(ServletConfig config) throws ServletException
{
contx = config.getServletContext();
}
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
try
{
OutputStream outer = res.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outer);
String userName = (String) req.getSession().getAttribute("username");
oos.writeChars(userName);
oos.flush();
oos.close();
}
catch (Throwable e)
{
e.printStackTrace();
}
}
}
Calling.js
function getUserInfo()
{
var userInfoHttp;
if (window.XMLHttpRequest)
{
userInfoHttp = new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
userInfoHttp = new ActiveXObject("Microsoft.XMLHTTP")
}
userInfoHttp.open("POST", "GetCurrentUserInfo", false);
userInfoHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
userInfoHttp.onreadystatechange = function ()
{
if (userInfoHttp.readyState == 4)
{
if (userInfoHttp.status == 200)
{
var res = TrimString(userInfoHttp.responseText);
alert(res);
}
}
}
userInfoHttp.send(null);
isAnnotationUpdate = false;
}
I res i am getting userName with some extra characters like this:- "���w�s�#�s�.�c�o�m"
In actual my userName is s#s.com only.
I think that 2 things can fix your encoding problem
Firstly use the OutputStreamWriter and give it encoding value
OutputStream stream = response.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
String userName=(String)req.getSession().getAttribute("username");
writer.write(userName);
writer.flush();
and then make sure your response has the correct encoding
response.setCharacterEncoding("UTF-8");
Related article : Unexpected character when downloading file client side from a servlet
UPDATE
And something else i forgot in original answer. Set the ContentTyoe of the response Object to text/plain because you are actually returning plain text chars
response.setContentType("text/plain");