How to capture the requests using JAVA servlets - java

I need to capture all the http/https requests that are going through the browsers of my system using JAVA servlets.
Can I achieve that?

going through the browsers of my system
You can do this is with an implementation of ServletRequestListener::requestInitialized(ServletRequestEvent sre)
The Documentation say:
requestInitialized(ServletRequestEvent sre)
Receives notification that a ServletRequest is about to come into scope of the web application.
The class could look like this:
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Map.Entry;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
#WebListener
public class RequestListener implements ServletRequestListener {
public RequestListener() {}
public void requestDestroyed(ServletRequestEvent sre) {}
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
System.out.println("Timestamp: " + new Timestamp(System.currentTimeMillis()));
System.out.println("SessionId: " + request.getSession(false));
System.out.println("RequestURL: " + request.getRequestURL());
System.out.println("Method: " + request.getMethod());
System.out.println("Parameters: ");
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
System.out.println(entry.getKey() + " = " + Arrays.asList(entry.getValue()));
}
}
}
In the console you get something like this:
Timestamp: 2017-01-25 19:12:04.36
SessionId: null
RequestURL: https://localhost:8181/jee6/ResponseFilterTest/Fiz
Method: GET
Parameters:
p1 = [v1]
p2 = [v2]
Instead in the console you can store the data in a DB or write to a log.
If you need to differentiate between local and remote requests you can use request.getRemoteAddr(). For local requests it is 127.0.0.1

Related

Creating cookie in vertx

I want to create a simple cookie using vertx.
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import java.util.Date;
public class HttpVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/opt-out").handler(this::optOut);
System.out.println("Server started # 3000");
server.requestHandler(router::accept).listen(3000);
}
public void optOut(RoutingContext context) {
HttpServerRequest request = context.request();
HttpServerResponse response = context.response();
response.putHeader("content-type", "text-plain");
response.setChunked(true);
response.write("hellow world");
Cookie cookie = Cookie.cookie("foo", "bar");
context.addCookie(cookie);
response.end();
}
}
But when I check the browser, I see not cookies stamped by the name "foo", having value "bar". What am I doing wrong?
Also, how can I access all the cookies that is stamped?
This is how a cookie is set in Vertx.
#Override
public void start(Future<Void> future) {
Router router = Router.router(vertx);
router.route().handler(CookieHandler.create());
router.get("/set-cookie").handler(this::setCookieHandler);
}
public void setCookieHandler(RoutingContext context) {
String name = "foo";
String value = "bar";
long age = 158132000l; //5 years in seconds
Cookie cookie = Cookie.cookie(name,value);
String path = "/"; //give any suitable path
cookie.setPath(path);
cookie.setMaxAge(age); //if this is not there, then a session cookie is set
context.addCookie(cookie);
context.response().setChunked(true);
context.response().putHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
context.response().putHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET");
context.response().write("Cookie Stamped -> " + name + " : " +value);
context.response().end();
}
Thanks.
First, you need to add a CookieHandler in your Router.
This is the JavaDoc for addCookie method:
router.route().handler(CookieHandler.create());
/**
* Add a cookie. This will be sent back to the client in the response. The context must have first been
* to a {#link io.vertx.ext.web.handler.CookieHandler} for this to work.
*
* #param cookie the cookie
* #return a reference to this, so the API can be used
So, use the ".end()" method in response instead ".write()"
response.end("hellow world");

WebSocket and Endpoint

My IDE : NetBeans, GlassFish.
I am trying to understand how GlassFish execute and run the Endpoint!
I understand Glassfish as a webserver creates new Endpoint instance for each connection, and the Set : peers in the code appears as one global variable for every instance of endpoint.
My question is : how to add another global variable(s) so every instance of endpoint can access it?
enter code here
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint("/echo")
public class EchoServer {
/**
* #OnOpen allows us to intercept the creation of a new session.
* The session class allows us to send data to the user.
* In the method onOpen, we'll let the user know that the handshake was
* successful.
*/
private static final Set<Session > peers = Collections.synchronizedSet(new HashSet<Session >());
#OnOpen
public void onOpen(Session session){
System.out.println(session.getId() + " has opened a connection");
try {
peers.add(session);
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}
#OnMessage
public void onMessage(String message, Session session) throws IOException{
System.out.println("Message from " + session.getId() + ": " + message);
for (Session peer : peers) {
peer.aplayer.getBasicRemote().sendText(" Message from " + session.getId()+" : "+message);
}
}`enter code here`
#OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has ended");
peers.remove(session);
}
}

Can't read from datastore

Creating the entity and setting the property
package pack.exp;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
#SuppressWarnings("serial")
public class IkaiLanServlet extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws...
{
Entity alice = new Entity("Person", "Alice");
alice.setProperty("gender", "female");
alice.setProperty("age", 20);
Key bobKey = KeyFactory.createKey("Person", "Bob");
Entity bob = new Entity(bobKey);
bob.setProperty("gender", "male");
bob.setProperty("age", "23");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(alice);
datastore.put(bob);
resp.setContentType("text/plain");
resp.getWriter().println("Bye Bye");
}
}
In the same package creating another servlet
package pack.exp;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
public class Read extends HttpServlet
{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws...
{
// TODO Auto-generated method stub
super.doGet(req, resp);
Key bobKey = KeyFactory.createKey("Person", "Bob");
Key aliceKey = KeyFactory.createKey("Person", "Alice");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity alice, bob;
try {
alice = datastore.get(aliceKey);
bob = datastore.get(bobKey);
Long aliceAge = (Long) alice.getProperty("age");
Long bobAge = (Long) bob.getProperty("age");
System.out.println("Alice’s age: " + aliceAge);
System.out.println("Bob’s age: " + bobAge);
}
catch (EntityNotFoundException e)
{
// Alice or Bob doesn't exist!
}
}
}
When I am deploying the app the output is "Bye Bye". Why it is not reading the entity.
Please help me i am new to google app engine datastore..
When you go to whatever URL you have mapped to IkaiLanServlet, it will respond with "Bye Bye" because you called resp.getWriter().println("Bye Bye"). To read the entity, change
System.out.println("Alice’s age: " + aliceAge);
System.out.println("Bob’s age: " + bobAge);
to
resp.setContentType("text/plain");
resp.getWriter().println("Alice’s age: " + aliceAge);
resp.getWriter().println("Bob’s age: " + bobAge);
According to the docs (https://developers.google.com/appengine/docs/java/#Java_Logging):
Everything the servlet writes to the standard output stream (System.out) and standard error stream (System.err) is captured by App Engine and recorded in the application logs. Lines written to the standard output stream are logged at the "INFO" level, and lines written to the standard error stream are logged at the "WARNING" level.
To see the output in your browser, you must use resp.
Also, be sure that you visit the URL's for IkaiLanServlet and then Read, in that order, to ensure the entities are in the datastore.

How can I know how many concurrent flows are currently active

Does Spring-WebFlow provide a way of getting to know the number of flows currently executing ?
I could work around it with a global bean, but maybe WebFlow provides a solution out-of-the-box.
Edit: As requested, here the so called "Global Bean" solution based on a
FlowExecutionListenerAdapter
package your.package;
import org.apache.log4j.Logger;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.definition.StateDefinition;
import org.springframework.webflow.definition.TransitionDefinition;
import org.springframework.webflow.execution.FlowExecutionListenerAdapter;
import org.springframework.webflow.execution.FlowSession;
import org.springframework.webflow.execution.RequestContext;
public class FlowExecutionListener extends FlowExecutionListenerAdapter {
private static Logger logger = Logger.getLogger(FlowExecutionListener.class);
private int sessionCount = 0;
#Override
public void sessionStarted(final RequestContext context, final FlowSession session) {
super.sessionStarted(context, session);
sessionCount++;
logger.debug("sessionStarted, state: " + session.getState().getId() + ", count: " + sessionCount);
}
#Override
public void sessionEnded(final RequestContext context, final FlowSession session, final String outcome, final AttributeMap output) {
super.sessionEnded(context, session, outcome, output);
sessionCount--;
logger.debug("sessionEnded, state: " + session.getState().getId() + ", count: " + sessionCount);
}
}
The bean must be registered at Spring-level:
<bean id="flowExecutionListener" class="your.package.FlowExecutionListener" />
Edit2:
If you have more than one WebFlow in your application, this would count all the active flows. In case you want to account them separately, you can get the flow's ID with session.getDefinition().getId().

User (session) count in cluster

Is there a good way to get the logged in user count in a Java web application that is running in a cluster?
I wrote a simple HttpSessionListener with a static field, but I suppose this doesn't work in cluster. I can see there is a Spring Security solution, but I read in some forums that this is still not ok in cluster.
The product in which I have to implement this user count is trying to be application server independent, currently we support Tomcat, Weblogic and JBoss. At the moment I need a solution for Weblogic 10.3 clusters.
You can maintain the counter in database which will work in cluster env.
A simple tutorial to demonstrate how to determine active users / sessions in a Java Web Application.
package com.hubberspot.javaee.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
#WebListener
public class OnlineUsersCounter implements HttpSessionListener {
private static int numberOfUsersOnline;
public OnlineUsersCounter() {
numberOfUsersOnline = 0;
}
public static int getNumberOfUsersOnline() {
return numberOfUsersOnline;
}
public void sessionCreated(HttpSessionEvent event) {
System.out.println("Session created by Id : " + event.getSession().getId());
synchronized (this) {
numberOfUsersOnline++;
}
}
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("Session destroyed by Id : " + event.getSession().getId());
synchronized (this) {
numberOfUsersOnline--;
}
}
}
Running the below servlet on three different browsers will provide output as : (see fig below)
package com.hubberspot.javaee;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.hubberspot.javaee.listener.OnlineUsersCounter;
// #WebServlet annotation has a initParams field which takes
// in initialization parameters for a servlet.
// #WebInitParam annotation takes in a name and value for the
// initialization parameters for the current Servlet.
#WebServlet(name = "HelloWorldServlet" , urlPatterns = { "/HelloWorldServlet" }
, initParams = { #WebInitParam(name = "user" , value = "Jonty") })
public class HelloWorldServlet extends HttpServlet {
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// sessionCreated method gets executed
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);
try {
out.println("<html>");
out.println("<body>");
out.println("<h2>Number of Users Online : "
+ OnlineUsersCounter.getNumberOfUsersOnline()
+ "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
Output of the program :
Eclipse Browser ->
Firefox Browser ->
Internet Explorer Browser ->
Console Output ->
For more: http://www.hubberspot.com/2013/09/how-to-determine-active-users-sessions.html

Categories