Last active
June 3, 2021 17:18
-
-
Save rybalkinsd/73b83901afc0c12d77ba65cb219eeb21 to your computer and use it in GitHub Desktop.
Simple chat. Jersey + Jetty + Html +Js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.atom.http.server; | |
import org.apache.logging.log4j.LogManager; | |
import org.apache.logging.log4j.Logger; | |
import org.eclipse.jetty.util.ConcurrentArrayQueue; | |
import javax.ws.rs.Consumes; | |
import javax.ws.rs.FormParam; | |
import javax.ws.rs.GET; | |
import javax.ws.rs.POST; | |
import javax.ws.rs.Path; | |
import javax.ws.rs.Produces; | |
import javax.ws.rs.QueryParam; | |
import javax.ws.rs.core.Response; | |
@Path("/") | |
public class ChatResource { | |
private static final Logger log = LogManager.getLogger(ChatResource.class); | |
private static final ConcurrentArrayQueue<String> logined = new ConcurrentArrayQueue<>(); | |
private static final ConcurrentArrayQueue<String> chat = new ConcurrentArrayQueue<>(); | |
@POST | |
@Consumes("application/x-www-form-urlencoded") | |
@Path("/login") | |
public Response login(@QueryParam("name") String name) { | |
if (name.length() < 1) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("Too short name, sorry :(").build(); | |
} | |
if (name.length() > 30) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("Too long name, sorry :(").build(); | |
} | |
if (name.toLowerCase().contains("gitler")) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("Gitler not allowed, sorry :(").build(); | |
} | |
if (logined.contains(name)) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("Already logined").build(); | |
} | |
log.info("[" + name + "] logined"); | |
logined.add(name); | |
chat.add("[" + name + "] joined"); | |
return Response.ok().build(); | |
} | |
@GET | |
@Produces("text/plain") | |
@Path("/online") | |
public Response online() { | |
return Response.ok(String.join("\n", logined)).build(); | |
} | |
@POST | |
@Consumes("application/x-www-form-urlencoded") | |
@Path("/say") | |
public Response say(@QueryParam("name") String name, @FormParam("msg") String msg) { | |
if (name == null) { | |
return Response.status(Response.Status.UNAUTHORIZED).entity("Name not provided").build(); | |
} | |
if (!logined.contains(name)) { | |
return Response.status(Response.Status.UNAUTHORIZED).entity("Not logined").build(); | |
} | |
if (msg == null) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("No message provided").build(); | |
} | |
if (msg.length() > 140) { | |
return Response.status(Response.Status.BAD_REQUEST).entity("Too long message").build(); | |
} | |
log.info("[" + name + "]: " + msg); | |
chat.add("[" + name + "]: " + msg); | |
return Response.ok().build(); | |
} | |
@GET | |
@Produces("text/plain") | |
@Path("/chat") | |
public Response chat() { | |
return Response.ok(String.join("\n", chat)).build(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.atom.http.server; | |
import javax.ws.rs.container.ContainerRequestContext; | |
import javax.ws.rs.container.ContainerResponseContext; | |
import javax.ws.rs.container.ContainerResponseFilter; | |
import javax.ws.rs.ext.Provider; | |
import java.io.IOException; | |
@Provider | |
public class CrossBrowserFilter implements ContainerResponseFilter { | |
@Override | |
public void filter(ContainerRequestContext request, | |
ContainerResponseContext response) throws IOException { | |
response.getHeaders().add("Access-Control-Allow-Origin", "*"); | |
response.getHeaders().add("Access-Control-Allow-Headers", | |
"origin, content-type, accept, authorization"); | |
response.getHeaders().add("Access-Control-Allow-Credentials", "true"); | |
response.getHeaders().add("Access-Control-Allow-Methods", | |
"GET, POST, PUT, DELETE, OPTIONS, HEAD"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.atom.http.server; | |
import org.eclipse.jetty.server.Handler; | |
import org.eclipse.jetty.server.Server; | |
import org.eclipse.jetty.server.handler.ContextHandler; | |
import org.eclipse.jetty.server.handler.ContextHandlerCollection; | |
import org.eclipse.jetty.server.handler.ResourceHandler; | |
import org.eclipse.jetty.servlet.ServletContextHandler; | |
import org.eclipse.jetty.servlet.ServletHolder; | |
public class HttpServer { | |
public static void main(String[] args) throws Exception { | |
ContextHandlerCollection contexts = new ContextHandlerCollection(); | |
contexts.setHandlers(new Handler[] { | |
createChatContext(), | |
createResourceContext() | |
}); | |
Server jettyServer = new Server(8080); | |
jettyServer.setHandler(contexts); | |
jettyServer.start(); | |
} | |
private static ServletContextHandler createChatContext() { | |
ServletContextHandler context = new ServletContextHandler(); | |
context.setContextPath("/chat/*"); | |
ServletHolder jerseyServlet = context.addServlet( | |
org.glassfish.jersey.servlet.ServletContainer.class, "/*"); | |
jerseyServlet.setInitOrder(0); | |
jerseyServlet.setInitParameter( | |
"jersey.config.server.provider.packages", | |
"ru.atom.http" | |
); | |
jerseyServlet.setInitParameter( | |
"com.sun.jersey.spi.container.ContainerResponseFilters", | |
CrossBrowserFilter.class.getCanonicalName() | |
); | |
return context; | |
} | |
private static ContextHandler createResourceContext() { | |
ContextHandler context = new ContextHandler(); | |
context.setContextPath("/"); | |
ResourceHandler handler = new ResourceHandler(); | |
handler.setWelcomeFiles(new String[]{"index.html"}); | |
String serverRoot = HttpServer.class.getResource("/static").toString(); | |
System.out.println(serverRoot); | |
handler.setResourceBase(serverRoot); | |
context.setHandler(handler); | |
return context; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
var host = "localhost"; | |
var port = 8080; | |
</script> | |
<html> | |
<style> | |
:root { | |
background: #336666; | |
} | |
.chat { | |
background: #99CCCC; | |
font-family: "Courier New", Courier, monospace; | |
padding: 7px; | |
margin: 0 0 1em; | |
overflow: auto; | |
} | |
.form { | |
height: 85%; | |
} | |
.msginput { | |
width: 80%; | |
} | |
.sendbutton { | |
width: 15%; | |
} | |
#header { | |
background: #336666; | |
padding: 10px; | |
padding-bottom: 0; | |
} | |
#body { | |
padding: 10px; | |
padding-top: 0; | |
padding-bottom: 30px; /* Height of the footer */ | |
} | |
#footer { | |
padding: 10px; | |
position: absolute; | |
bottom: 0; | |
width: 100%; | |
height: 30px; /* Height of the footer */ | |
background: #336666; | |
} | |
</style> | |
<body> | |
<div id="header"> | |
<form method="POST" id="nameform" action="javascript:void(null);" onsubmit="login()"> | |
<input id="name" name="name" value="" style="font-size:medium" type="text"> | |
<input value="Login" style="font-size:large" type="submit"> | |
</form> | |
</div> | |
<div id="body"> | |
<div id="history" class="chat form"></div> | |
</div> | |
<div id="footer"> | |
<form method="POST" id="msgform" action="javascript:void(null);" onsubmit="say()"> | |
<input id="msg" name="msg" class="msginput" value="" style="font-size:medium" type="text"> | |
<input value="Send" class="sendbutton" style="font-size:large" type="submit"> | |
</form> | |
</div> | |
</body> | |
</html> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
<script> | |
function loadHistory() { | |
var settings = { | |
"crossDomain": true, | |
"url": "http://" + host + ":" + port + "/chat/chat", | |
"method": "GET", | |
} | |
$.ajax(settings).done(function (response) { | |
$( "#history" ).html(response.replace(/\n/g, "<br />")) | |
$( "#history" ).scrollTop( $( "#history" )[0].scrollHeight ); | |
}).fail(function (jqXHR, textStatus) { | |
console.log(jqXHR.status + " " + jqXHR.statusText + ". " + jqXHR.responseText); | |
}); | |
} | |
setInterval(loadHistory, 1000); | |
</script> | |
<script> | |
function say() { | |
var msg = $('#msgform').serialize(); | |
var name = $('#nameform').serialize(); | |
var settings = { | |
"method": "POST", | |
"crossDomain": true, | |
"url": "http://" + host + ":" + port + "/chat/say?"+name, | |
"data": msg | |
} | |
$.ajax(settings).done(function(response) { | |
$('#msgform').trigger("reset"); | |
loadHistory(); | |
}).fail(function (jqXHR, textStatus) { | |
alert(jqXHR.status + " " + jqXHR.statusText + ". " + jqXHR.responseText); | |
console.log(jqXHR.status + " " + jqXHR.statusText + ". " + jqXHR.responseText); | |
}); | |
} | |
</script> | |
<script> | |
function login() { | |
var name = $('#nameform').serialize(); | |
var settings = { | |
"method": "POST", | |
"crossDomain": true, | |
"url": "http://" + host + ":" + port + "/chat/login?"+name, | |
} | |
$.ajax(settings).done(function(response) { | |
loadHistory(); | |
}).fail(function (jqXHR, textStatus) { | |
alert(jqXHR.status + " " + jqXHR.statusText + ". " + jqXHR.responseText); | |
console.log(jqXHR.status + " " + jqXHR.statusText + ". " + jqXHR.responseText); | |
}); | |
} | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
appender.console.type = Console | |
appender.console.name = STDOUT | |
appender.console.layout.type = PatternLayout | |
appender.console.layout.pattern = %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %m%n | |
rootLogger.level = info | |
rootLogger.appenderRef.stdout.ref = STDOUT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment