I'm a new bird learning Servlet. When I use cookie in Servlet, I found cookie can't be added after visiting web page.
Here's my code:
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LastAccessServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String lastAccessTime = null;
Cookie[] cookies = req.getCookies();
PrintWriter writer = resp.getWriter();
for (int i = 0; cookies != null && i < cookies.length; ++i){
if ("lastAccess".equals(cookies[i].getName())) {
lastAccessTime = cookies[i].getValue();
break;
}
}
if (lastAccessTime == null){
writer.println("Your first visit.");
} else {
writer.println("Last time" + lastAccessTime);
}
String currentTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("lastAccess", currentTime);
cookie.setMaxAge(999999999);
cookie.setPath("/");
resp.addCookie(cookie);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
Here's my WebPage:
No matter how many times I refresh, reload or change browsers, the result is the same.
I check the cookies in my edge browser.
The cookie hasn't the value name lastAccess I added, so I think the problem is in resp.addCookie(cookie);.But don't know how to solve it.
Your problem is not actually with the code/logic but data here. You are trying to set a cookie value which is more like a Date string looking like 2022-10-01 03:01:22.
The cookie value here is illegal. As per the RFC6265, you are not allowed to have some of the special characters in the cookie. A more detailed description is available with this answer
You can solve it by changing may be the way you form the cookie value. For eg use the timestamp instead of date string. Like below.
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String lastAccessTime = null;
Cookie[] cookies = req.getCookies();
PrintWriter writer = resp.getWriter();
for (int i = 0; cookies != null && i < cookies.length; ++i){
if ("lastAccess".equals(cookies[i].getName())) {
lastAccessTime = cookies[i].getValue();
break;
}
}
if (lastAccessTime == null){
writer.println("Your first visit.");
} else {
writer.println("Last time" + new Date(Long.parseLong(lastAccessTime)));
}
String currentTime = String.valueOf( new Date().getTime());
Cookie cookie = new Cookie("lastAccess", currentTime);
cookie.setMaxAge(999999999);
cookie.setPath("/");
resp.addCookie(cookie);
}
Related
There is a servlet that accepts files from the client and stores them in a folder.
It is now necessary to list the files from this folder and create links to them (that is, click on the file name and it's downloaded from you).
Now just output a list of files in the form of text. How to create links to them? I read that for this it is enough to expose the headers, but how this is done and has not been found.
Sample Code:
public class FileListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public FileListServlet() {
super();
}
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String param = "/dirs";
PrintWriter w = res.getWriter();
res.setContentType("text/html");
String root="/dirs";
java.io.File dir = new java.io.File(root);
File[] fileList = dir.listFiles();
w.println("<H2><FONT COLOR=TEAL>" + "Total number of files in the choosen directory - " +
fileList.length + "</FONT></H2>");
w.println("<H3><FONT COLOR=PURPLE>" +
"Directory path - " + param + "</FONT></H3><HR>");
w.println("<TABLE BORDER=0 CELLSPACING=5>");
for(int i = 0; i < fileList.length; i++)
printName(fileList[i], w);
w.println("</TABLE><HR>");
}
private void printName(File name, PrintWriter output)
{
String type = name.isDirectory()
? " (Directory)" : " (File)";
output.println("<TR><TD>" + type + "</TD><TD><FONT COLOR=BLUE>"
+ name.getName() + "</FONT></TD></TR>");
}
public String getServletInfo()
{
return "This servlet shows a content of a directory" +
"mentioned in dirToShow parameter or property.";
}
}
I solved my problem. In case someone needs it or someone knows a more beautiful way.
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FileListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public FileListServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter printWriter = response.getWriter();
response.setContentType("text/html");
File currentFolder = new File(".");
File workingFolder = new File(currentFolder, "Sorted files");
String root = workingFolder.getAbsolutePath();
java.io.File dir = new java.io.File(root);
File[] fileList = dir.listFiles();
printWriter.println("<H2><FONT COLOR=TEAL>" + "Total number of files in the choosen directory - " +
fileList.length + "</FONT></H2>");
printWriter.println("<H3><FONT COLOR=PURPLE>" +
"Directory path - " + root + "</FONT></H3><HR>");
printWriter.println("<TABLE BORDER=0 CELLSPACING=5>");
for(int i = 0; i < fileList.length; i++) {
printName(fileList[i], printWriter);
}
printWriter.println("</TABLE><HR>");
}
private void printName(File file, PrintWriter output)
{
System.out.println(file.getName());
output.println("<tr><td><a href=\"https://Upload/DownloadServlet?name="
+file.getName()+"\">" + file.getName() + "</a></td></tr>" );
}
public String getServletInfo()
{
return "This servlet shows a content of a directory" +
"mentioned in dirToShow parameter or property.";
}
}
And DownloadServlet
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DownloadServlet
*/
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public DownloadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String name = request.getParameter("name");
String fileType = "multipart/form-data";
response.setContentType(fileType);
response.setHeader("Content-disposition", "attachment; filename=" + name);
File currentFolder = new File(".");
File workingFolder = new File(currentFolder, "Sorted files");
String root = workingFolder.getAbsolutePath();
File file = new File(root + File.separator + name);
OutputStream output = response.getOutputStream();
FileInputStream input = new FileInputStream(file);
byte[] buffer = new byte[4096];
int lenght;
while( ( lenght = input.read(buffer) ) > 0 ) {
output.write(buffer, 0, lenght);
}
input.close();
output.flush();
output.close();
response.getOutputStream().flush();
response.getOutputStream().close();
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
I have three programs (a-b-c): a starts b that handles c, when c ends a restarts b. I can only change b, but it is unstable because it is restarted. I was thinking of solving my problems with a servlet service that receives b data and errors and displays them on a web page immediately. I tried two ways: 1. Receive data in a Thread parallel to the servlet and share it with it (I did not succeed); 2. Receive data from a client and share it with ServletContext and refresh the page with sent event but skip lines, even with retry: 100, and repeat the last one when there are no new data. Is there a way to send data to all servlet clients only when they are new? Is there a better solution considering that b is restarted and that I have to limit the ports used?
--UPDATE--
Servlet.java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
#WebServlet(name = "Servlet", urlPatterns = {"/Servlet", "/test"})
public class Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Connection", "keep-alive");
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache");
String datain = request.getParameter("StringIn");
String dataold = request.getParameter("StringOld");
PrintWriter writer = response.getWriter();
if (datain == null) {
boolean test = getServletContext().getAttribute("actualData").equals(request.getParameter("StringOld"));
if (!test) {
writer.write("data: " + getServletContext().getAttribute("actualData") +"\n\n");
writer.write("retry: 500");
}
else {
writer.write("data: \n\n");
writer.write("retry: 1000");
}
}
else {
getServletContext().setAttribute("actualData", datain);
writer.write("data receive!\n\n");
}
writer.flush();
writer.close();
}
}
Script index.jsp
var eventSource = null;
var oldmessage = "";
var path = "http://localhost:8080/Servlet?StringaOld=";
function start() {
eventSource = new EventSource(path + oldmessage);
eventSource.onopen = function () {
};
eventSource.onmessage = function (message) {
var mex = message.data;
message.data = null;
if (mex != null) {
oldmex = mex;
testo.value += mex + "\n";
}
};
eventSource.onerror = function (error) {
eventSource = new EventSource(path + encodeURI(oldmessage));
};
Start.disabled = true;
}
function stop() {
eventSource.close();
Start.disabled = false;
}
I have set cookies in a servlet class and read those cookies values in another servlet class. In another servlet class along with the set cookies values, I am getting some unusual values.
My Home.java servlet class results set ::
first result
Hello JSESSIONID, Hello A502A7144AE035ED9B1A2549F5C7B74B
Hello first_name, Hello RACHEL
Hello last_name, Hello KIM
second result
Hello JSESSIONID, Hello A502A7144AE035ED9B1A2549F5C7B74B
Hello first_name, Hello CAIRO
Hello last_name, Hello SENGAL
in both the results I am getting the set cookies values and names but along with them I am getting JSESSIONID and A502A7144AE035ED9B1A2549F5C7B74B. I can't understand from where do these cookies values are appearing? How can I remove this? Why are these values appearing?
My code :
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Authenticate
*/
#WebServlet("/Authenticate")
public class Authenticate extends HttpServlet {
private static final long serialVersionUID = 1L;
public Authenticate() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String firstname = request.getParameter("firstname");
String lastname = request.getParameter("lastname");
out.print("Welcome "+ firstname);
// Create cookies for first and last names.
Cookie f_name = new Cookie("first_name", firstname);
Cookie l_name = new Cookie("last_name", lastname);
// Add both the cookies in the response header.
response.addCookie( f_name );
response.addCookie( l_name );
//creating submit button
out.print("<form action='Home' method='post' >");
out.print("<input type='submit' value='cookie click' />");
out.print("</form>");
out.close();
}
catch(Exception ex)
{
System.out.println("exception occured");
System.out.println(ex.toString());
}
}
}
Code for Home servlet
#WebServlet("/Home")
public class Home extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public Home() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Cookie ck[] = request.getCookies();
if (ck != null) {
for (int i = 0; i < ck.length; i++) {
out.print("Hello " + ck[i].getName() + ", ");
out.print("Hello " + ck[i].getValue());
out.print("<br />");
}
}
out.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
I am having an issue where calling request.getParameter() returns null when large amounts of data are passed to the page. The header Content-Type is application/x-www-form-urlencoded. And the setting for maximum POST size is set to 12,582,912 bytes (i.e. maxPostSize=12582912) in server.xml.
Client Code
public class Send
{
public static int readTimeout = 30000;
public static int connectionTimeout = 10000;
public static void main(String[] args) throws IOException, JSONException
{
sendFile(1000,1);
}
public static void sendFile(int n,int m) throws IOException, JSONException
{
String urlStr = "http://localhost:8080/sendChange";
URL url = new URL(urlStr);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setConnectTimeout(connectionTimeout);
httpConn.setReadTimeout(readTimeout);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
JSONArray list;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < m; i++)
{
list = new JSONArray();
for (int j = 0; j < n; j++)
{
list.put(getChange());
}
if(i==0)
{
stringBuilder.append("bulk=");
}
else
{
stringBuilder.append("&bulk_").append(i).append("=");
}
stringBuilder.append(list.toString());
}
int length = stringBuilder.toString().getBytes().length;
System.out.println(length);
httpConn.setRequestProperty("Content-Length", Integer.toString(stringBuilder.toString().getBytes().length));
DataOutputStream printout = new DataOutputStream(httpConn.getOutputStream());
printout.write(stringBuilder.toString().getBytes());
printout.close();
int responseCode = httpConn.getResponseCode();
System.out.println(responseCode);
}
Server Code
import org.json.JSONArray;
import org.json.JSONException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by mohan-4019 on 12/28/16.
*/
#WebServlet(name = "CollectorServlet")
public class CollectorServlet extends HttpServlet
{
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
String bulk = request.getParameter("bulk");
try
{
JSONArray bulkJSON = new JSONArray(bulk);
int length = bulkJSON.length();
}
catch (JSONException e)
{
System.out.println(e);
}
}
}
The call to getChange() returns a JSONObject, which has size 7kb.
It works perfectly for data with small size.
Large data can read from request.getInputStream().
I am trying to write a filter that can retrieve the request URL, but I'm not sure how to do so.
Here is what I have so far:
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class MyFilter implements Filter {
public void init(FilterConfig config) throws ServletException { }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
chain.doFilter(request, response);
String url = ((HttpServletRequest) request).getPathTranslated();
System.out.println("Url: " + url);
}
public void destroy() { }
}
When I hit a page on my server, the only output I see is "Url: null".
What is the correct way to get the requested URL from a given ServletRequest object in a Filter?
Is this what you're looking for?
if (request instanceof HttpServletRequest) {
String url = ((HttpServletRequest)request).getRequestURL().toString();
String queryString = ((HttpServletRequest)request).getQueryString();
}
To Reconstruct:
System.out.println(url + "?" + queryString);
Info on HttpServletRequest.getRequestURL() and HttpServletRequest.getQueryString().
Building on another answer on this page,
public static String getCurrentUrlFromRequest(ServletRequest request)
{
if (! (request instanceof HttpServletRequest))
return null;
return getCurrentUrlFromRequest((HttpServletRequest)request);
}
public static String getCurrentUrlFromRequest(HttpServletRequest request)
{
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if (queryString == null)
return requestURL.toString();
return requestURL.append('?').append(queryString).toString();
}
If you use Spring, you can use OncePerRequestFilter or others.
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.stereotype.Component;
#Component
public class MyFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String url = request.getRequestURL();
filterChain.doFilter(request, response);
}
}
request.getRequestURL();
Documentation