I'm trying to tracking valid user Ids in my Java servlet, can I implement HttpSessionListener this way ?
public class my_Servlet extends HttpServlet implements HttpSessionListener
{
String User_Id;
static Vector<String> Valid_User_Id_Vector=new Vector<String>();
private static int activeSessions=0;
public void sessionCreated(HttpSessionEvent se)
{
// associate User_Id with session Id;
// add User_Id to Valid_User_Id_Vector
Out(" sessionCreated : "+se.getSession().getId());
activeSessions++;
}
public void sessionDestroyed(HttpSessionEvent se)
{
if (activeSessions>0)
{
// remove User_Id from Valid_User_Id_Vector by identifing it's session Id
Out(" sessionDestroyed : "+se.getSession().getId());
activeSessions--;
}
}
public static int getActiveSessions()
{
return activeSessions;
}
public void init(ServletConfig config) throws ServletException
{
}
public void destroy()
{
}
protected void processRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
{
User_Id=request.getParameter("User_Id");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
processRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
processRequest(request, response);
}
public String getServletInfo()
{
return "Short description";
}
}
How to get the listener notified when a session ends ? I'm trying to bypass "/WEB-INF.web.xml" all together, is it doable ? Or does it make sense ?
This won't bypass /WEB-INF/web.xml. Furthermore, you'll end up with 2 instances of this class, not 1 performing both functions. I suggest you put this Vector in the ServletContext and have 2 separate classes.
In the servlet, you get to it via getServletContext(). In the listener, you'll do something like this:
public void sessionCreated(HttpSessionEvent se) {
Vector ids = (Vector) se.getSession().getServletContext().getAttribute("currentUserIds");
//manipulate ids
}
Related
I am coming to a problem where I have loginFilter where I dont want the user to access a page when they are logged in with the URL. So, all I want to do is redirect the user to the index page. Here is my code below. Thank you.
public class LoginFilter implements Filter {
#Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
String username = req.getHeader("username");
String password = req.getHeader("password");
if(username == null) {
chain.doFilter(request, response);
return;
}
try {
req.login(username, password);
chain.doFilter(request, response);
} catch (ServletException e) {
((HttpServletResponse)response).setStatus(StatusCodes.UNAUTHORIZED);
}
}
#Override
public void destroy() {
}
}
Change your method as :
HttpServletResponse res = (HttpServletResponse)response;
try {
req.login(username, password);
res.sendRedirect("/index");
} catch (ServletException e) {
// you can use SC_UNAUTHORIZED(401) from HttpServletResponse class as well
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
I wrote a method which return an Array converted as String. When calling this method in the main method and printing it out the array is filled. When I am calling the same method in the doGet method for printing it in my html file, the array is empty and it prints only: []
Normally the doGet method schould work because when the method return not the array but just "hello" the html file print the String.
Here ist the code:
public static String test(senderonpremise s){
String t;
//this should be printed
t = String.valueOf(s.arrivalList);
//startSending();
//this works in doGet()
//return "this works";
// when I return this it works in the main-method but not in DoGet()
return t;
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/event-stream");
resp.setCharacterEncoding("UTF-8");
senderonpremise s = new senderonpremise();
PrintWriter out = resp.getWriter();
String next = "data: " + test(s) + "\n\n";
out.write(next);
out.flush();
}
/**
public static void main(String[] args) {
senderonpremise s = new senderonpremise();
System.out.print(test(s));
}
**/
I recommend you using the JEaSSE library: https://github.com/mariomac/jeasse, which is lightweight and works out of the box with Servlets 3.x
#WebServlet(asyncSupported = true)
public class ExampleServlet1 extends HttpServlet {
EventTarget target;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
target = new ServletEventTarget(req).ok().open();
}
public void onGivenEvent(String info) {
target.send("givenEvent",info);
}
}
The init method gets called again and again on every request in servlet.
Here is the code:
public class PersonInfoController extends HttpServlet {
private static final long serialVersionUID = 1L;
public PersonInfoController() {
super();
}
public void init() throws ServletException {
Connection connection = Database.getConnection();
System.out.println("init method");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<PersonInfoServiceI> myList = new ArrayList();
PersonInfoServiceI instance = new PersonInfoServiceImpl();
myList = instance.getdata();
String jsonstring = new Gson().toJson(myList);
request.setAttribute("List", jsonstring);
RequestDispatcher rd = request.getRequestDispatcher("showdata.jsp");
rd.forward(request, response);
}
public void destroy() {
System.out.println("the destory");
}
}
According to your code init() should call only once when servlet will load on first request. Then after its destruction init() will be called again on new request. In between only your service method will be called. Your code is good having no logical mistakes.
Are you calling init method outside the servlet?
Can you attach you deployment descriptor?
I'm been writing a small login servlet. The login part works just fine, but when I press logout submit button - nothing happens.
Servlet code down bellow:
public class LoginServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 7638796169158385551L;
private Database database = Database.getInstance();
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.write("<html><head><title>Login form</title></head>");
if (!database.connected) {
outLoginForm(out);
} else {
out.write("Hello " + database.getLoginName() + "!");
outLogoutForm(out);
}
out.write("</body></html>");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (request.getParameter("loginsub") != null) {
if (isParameterEmpty(request, "login")
|| isParameterEmpty(request, "pass")) {
response.getWriter().write("Some fields are empty");
doGet(request, response);
}
try {
database.connect(request.getParameter("login"),
request.getParameter("pass"));
} catch (ExceptionInInitializerError ex) {
response.getWriter().write("Login or password is incorrect");
}
} else if (request.getParameter("logoutsub") != null) {
database.disconnect();
}
doGet(request, response);
}
private boolean isParameterEmpty(HttpServletRequest request,
String parameter) {
if (request.getParameter(parameter).isEmpty())
return true;
return false;
}
protected void outLoginForm(PrintWriter out) {
out.write("<FORM method =\"POST\">");
out.write("Login:<input type=\"text\"name=\"login\"><br>");
out.write("Password:<input type=\"password\"name=\"pass\"><br>");
out.write("<input type=\"submit\"name=\"loginsub\" value=\"Login\"/><br>");
out.write("</FORM><br>");
}
protected void outLogoutForm(PrintWriter out) {
out.write("<FORM method =\"POST>\">");
out.write("<input type=\"submit\"name=\"logoutsub\" value=\"Logout\"/><br>");
out.write("</FORM><br>");
}
}
Can anyone help me find out what's wrong? I'm new to JSP and java servlets.
There is one problem is below line (one extra > after POST
out.write("<FORM method =\"POST>\">");
replace it with
out.write("<FORM method =\"POST\">");
I tried to do...
Source
FilterHolder myHolder
= new FilterHolder(new Filter() {
public void init(FilterConfig fc) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
// HERE:
InputStream is = httpReq.getInputStream();
// (read is to a string and output it, works,
// but swallows all data forever)
fc.doFilter(httpReq, httpResp);
}
public void destroy() {
}
});
... but swallows all data and real servlets don't get anything.
I just want to "read" POST request contents and output them for debugging.
NOTE 1: I don't want to "intercept" requests, they should go through as before.
NOTE 2: An additional hint, how to do the same with POST responses would be very kind.
EDIT Replaced Reader with InputStream. Reader didn't work at all.
Got it! I'm using a wrapper for InputStream and OutputStream each.
Tested. Works for both directions.
HttpRequestCopyFilter
final class HttpRequestCopyFilter implements Filter {
private final OutputStream copyOutput;
public HttpRequestCopyFilter(OutputStream copyOutput) {
this.copyOutput = copyOutput;
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
private void flushCopy() throws IOException {
copyOutput.flush();
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
HttpServletRequestWrapper requestWrapper =
new HttpServletRequestWrapper(httpReq) {
#Override
public ServletInputStream getInputStream()
throws IOException {
final ServletInputStream original =
super.getInputStream();
return new ServletInputStream() {
#Override
public int read() throws IOException {
int c = original.read();
if (c >= 0) {
copyOutput.write(c);
flushCopy();
}
return c;
}
#Override
public int read(byte[] b) throws IOException {
int count = original.read(b);
if (count >= 0) {
copyOutput.write(b, 0, count);
flushCopy();
}
return count;
}
#Override
public int read(byte[] b, int off, int len)
throws IOException {
int count = original.read(b, off, len);
if (count >= 0) {
copyOutput.write(b, off, count);
flushCopy();
}
return count;
}
};
}
};
fc.doFilter(requestWrapper, httpResp);
}
}
HttpResponseCopyFilter
final class HttpResponseCopyFilter implements Filter {
private final OutputStream copyOutput;
public HttpResponseCopyFilter(OutputStream copyOutput) {
this.copyOutput = copyOutput;
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
HttpServletResponseWrapper responseWrapper =
new HttpServletResponseWrapper(httpResp) {
#Override
public ServletOutputStream getOutputStream()
throws IOException {
final ServletOutputStream original =
super.getOutputStream();
return new ServletOutputStream() {
#Override
public void write(int b) throws IOException {
original.write(b);
copyOutput.write(b);
flush();
}
#Override
public void write(byte[] b) throws IOException {
original.write(b);
copyOutput.write(b);
flush();
}
#Override
public void write(byte[] b, int off, int len)
throws IOException {
original.write(b, off, len);
copyOutput.write(b, off, len);
flush();
}
#Override
public void flush() throws IOException {
original.flush();
copyOutput.flush();
super.flush();
}
#Override
public void close() throws IOException {
original.close();
copyOutput.flush(); // DON'T CLOSE COPY-OUTPUT !!!
super.close();
}
};
}
};
fc.doFilter(httpReq, responseWrapper);
}
}
The Servlet specification states that getInputStream may interfere with e.g. getParameter(String name), see this. So after calling getInputStream you may not be able to use the request objects' 'higher level' functions.
You could configure Jetty's request logging and use logback together with TeeFilter. It seems to implement the behaviour you need (did never use it).
Given posts store their key=value pairs in the body which may be read using an InputStream, the very act of you reading the InputStream may consume it, meaning the IS is empty when the real servlet tries to check it.