reading from a text file in servlets - servlets

i have a login servlet from where i take a username and a password. i have a credentials.txt file where i have saved a few usernames followed by their passwords adjacently in a single line. once i read the username and password in my logincheck servlet, i want to search it in credentials.txt. if a match is found, we are directed to a welcomepage servlet, and if not found, we are again directed to the login servlet. i am getting array out of bounds exception in my code.
Plz help correct my code.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user=request.getParameter("username");
String pass=request.getParameter("password");
File obj=new File("credentials.txt");
FileReader reader=new FileReader(obj);
BufferedReader in=new BufferedReader(reader);
String aks[],temp1,temp2;
int i=0;
String line=in.readLine();
while(line!=null){
aks=line.split("\t");
while(aks[i+1]!=null){
temp1=aks[i];
temp2=aks[i+1];
if(temp1.equals(user) && temp2.equals(pass)){
RequestDispatcher obj1=request.getRequestDispatcher("welcomepage");
obj1.forward(request,response);
}
line=in.readLine();
}
}
String errormsg="username and password do not match. Please re-enter";
request.setAttribute("errormsg",errormsg);
RequestDispatcher obj1=request.getRequestDispatcher("login");
obj1.forward(request,response);
}

It looks like you're thinking that aks[i+1]!=null will evaluate to false if the element aks[i+1] doesn't exist. But if the element doesn't exist, it won't evaluate to anything; you'll always the exception you mentioned (index out of bounds). Seems like maybe what you're looking to do is actually while (aks.length>1).

Related

Cannot call sendRedirect() after downloading PDF

I saw many questions like the one I am asking, but they are not exactly about what I am looking for.
I am using Command pattern, and want to create PDF-file and download it. Creating is perfect, but when I want to download it, it's starts downloading and throws an exception.
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
java.lang.IllegalStateException: getOutputStream() has already been called for this response
Here is my code from Command Pattern
#Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException, AppException {
String fontPath = request.getServletContext().getRealPath(AppConstants.FONT_PATH);
DBManager db = DBManager.getInstance();
String ticketCode = request.getParameter("ticketCode");
String place = request.getParameter("place");
int amountTickets = Integer.valueOf(place);
String flightName = Encoding.encoding(request.getParameter("flightName"));
User user = (User) request.getSession().getAttribute("client");
String locale = (String) request.getServletContext().getAttribute("currentLocale");
db.updateFlightTickets(flightName, --amountTickets);
///////create pdf document and represent it to the byte array
ByteArrayOutputStream baos =ReportCreator.createReport(locale, fontPath, ticketCode, place, user,
db.getFlightByName(flightName));
response.setContentType("application/pdf");
response.setContentLength(baos.size());
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"Ticket\"");
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
return Path.SUCCESS;
}
Here is my "success page", sorry but can not add more, not enough reputation
<fmt:message key="success_jsp.label.success" />
And here is my servlet code
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
process(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
process(request, response);
}
private void process(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String commandName = request.getParameter("command");
Command command = CommandContainer.get(commandName);
String forward = "";
try {
forward = command.execute(request, response);
} catch (AppException ex) {
request.setAttribute("errorMessage", ex.getMessage());
}
if (forward.equals(Path.SUCCESS)) {
response.sendRedirect(forward);
} else {
request.getRequestDispatcher(forward).forward(request, response);
}
}
Part of code in JSP, where click is calling the servlet
<td><button><fmt:message key="welcome_jsp.submit.buy_ticket" /></button></td>
How can i avoid it?
The exception says you are trying to working with the request/response once you redirect it or viceversa, and it's not valid.
Once you redirect a request, you cannot do anything else with the request/response, so getting the output stream and writing something to it is completely insane.
It's true about vice-versa situation, writing something and then redirect it will cause the browser will ignore the response data, or exception on server as I'm guessing you got.(but it depends on container)
So you either do not redirect the browser, or provide the pdf file with the target servlet/cgi where you are trying to redirect.
=================
And your current situation/problem:
Server sets the content-length, content-type,... and starts to write down some stream to the browser, since you haven't set any status, container will set default 200 OK which indicates there is some right response for the request.
Then browser will get some data(the pdf file) as 200 OK data(and consider it done), now how would you redirect the user once the response is almost done?!!?!!?!
I still do not understand why do you like to redirect a request when it's almost closed? you like to redirect the user after download complete? you cannot.

Safe login inside a web page(java servlet)

I create a web page which takes user naame and if it is true, it shows some information(using servlet) otherwise it return nothing
I have a question that is this standard approach or safe.
I know that I should use a database but simplifying code I did not use and session time out doesn't matter here I will handle it.
Is this method safe.
Thanks
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userName =request.getParameter("uname");
String passWord =request.getParameter("pass");
if(!userName.equals("admin"))
return;
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet fservlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>Hi " +userName+ "</h3>");
out.println("</body>");
out.println("</html>");
}
}
I dont really think it is a good way to follow. Because you are sending the username and password on the request object.. so if somebody track your request, they can easily see your credentials which is a security threat. If you are concern on such requirements on your question, I would like to suggest you to use some key encryption mechanism to first encrypt it on client side before passing it to server side.
example:
http://www.jcryption.org/
http://crypto.stanford.edu/sjcl/
hope this will provide you a thought !!

class variable set to null outside of a servlet

I wrote a simple servlet, in the doPost I got the user name and the password from a jspand authenticated the user by sending the password entered by the user to the data base(mysql). I got the data correctly and I am redirecting the user to another jsp page called welcome.jsp.
my question is , I wrote this method public String getUser(){return userNmae;}; I put it outside of the dopost method, however it is returning null. I have declared the variable userNmae as a class variable and when I debug , the variable contains a value in the dopost method , but it is null outside of the dopost method.why it is null outside of the dopost method?
I am calling getUser() method in the welcome.jsp page.
here is my code
public class UIclass extends HttpServlet {
public UIclass() { };
private String passWord = null;
private String userNmae = null;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("userName");
String password = request.getParameter("password");
Connection connection = null;
try {
connection = Connections.getConnection();
java.sql.PreparedStatement statement = connection.prepareStatement("SELECT PASSWORD,USERNAME FROM LOGIN where username =?");
statement.setString(1, name);
ResultSet resultset = statement.executeQuery();
while (resultset.next()) {
passWord = resultset.getString("PASSWORD");
userNmae = resultset.getString("USERNAME");
}
} catch (Exception e) {
// TODO: handle exception
} finally {
if (connection != null)
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
};
}
if (passWord.equalsIgnoreCase(password)) {
RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp");
rd.forward(request, response);
}
}
public String getUser() {
return userNmae;
}
}
I'll answer by giving you a simpler example of what your code is actually doing:
Bottle bottle1 = new Bottle();
bottle1.setMessage("Hi there");
Bottle bottle2 = new Bottle();
System.out.println(bottle2.getMessage());
What would you expect this program to display? I would expect null, because you set a message on bottle1, and read the message from bottle2. These are two different bottles. When you put a message in a bottle, the message is in that bottle, not in the other bottles.
Your code does the same thing.
The servlet container creates an instance (unique) of UIclass. This is equivalent to creating the first bottle in my example.
The servlet is invoked when you send an HTTP request. It sets the user attribute in the servlet. This is equivalent to bottle1.setMessage("Hi there") in my example.
The container executes your JSP, which contains the code
<jsp:useBean id="uiclass" class="com.servlet.UIclass" scope="request">
This creates a new UIClass instance. It is equivalent to creating the second bottle in my example.
The JSP calls uiclass.getUser(). This is equivalent to getting the message from the second bottle in my example.
There are many, many things wrong in your code:
You shouldn't use scriptlets, and jsp:useBean tags
You should never create instances of servlets by yourself. A servlet is meant to be instanciated and called by the container.
You should realize that a unique servlet instance is called to serve, concurrently, all the requests of all the users to this servlet URL. Storing user-specific data in servlet attributes is thus really wrong
You probably want the user name to be available for all the subsequent requests of this user. That's what the HTTP session is for. You should store the user as an attribute of the HTTP session: request.getSession().setAttribute("userName", userName)
The JSP should use the JSP EL and the JSTL to access beans stored in the request or the session by the servlet:
<c:out value="${userName}"/>

How do I extract the username and password out of a URL in a servlet filter?

I've created a BasicAuthFilter and it has this signature:
#Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException
This is working if someone calls the filter with an Authorization header set the right way. But, if someone on chrome or firefox visits the url like this:
http://username:password#localhost:8888
The browsers are not populating the Authorization header with that information (which surprised me). I looked at the information sent by chrome and the username and password are in the request URL but nowhere else.
I can't figure out how to extract that information from the URL. I've tried a lot of getters on the HttpServletRequest, but haven't found anything that gives me the username and password.
NOTE: Yes, I know this is insecure, it's just really convenient to use when you're trying to test your system.
URL url = new URL(custom_url);
String userInfo = url.getUserInfo();
String[] userInfoArray = userInfo.split(":");
System.out.println("username"+userInfoArray[0]);
System.out.println("password"+userInfoArray[1]);
My coworker found this thread that implies this isn't possible in modern browsers. They refuse to send the username:password part of a url over the wire for security reasons.
I'll add something to this answer
If the password contains the character :, you must specify a limit on your split.
So:
String[] userInfoArray = userInfo.split(":");
Becomes:
String[] userInfoArray = userInfo.split(":", 2);
2 means the pattern : is applied only one time (so the resulting length array is at maximum 2)
For passwords with '#', e.g. "http://user:p#ssw0rd#private.uri.org/some/service":
final String authority = uri.getAuthority();
if (authority != null) {
final String[] userInfo = authority.split(":", 2);
if (userInfo.length > 1) {
this.username = userInfo[0];
int passDelim = userInfo[1].lastIndexOf('#');
if (passDelim != -1) {
this.password = userInfo[1].substring(0, passDelim);
}
}
}
Note that in this case trying to use getUserInfo() won't help since userInfo of the URI is null.

How to get a form parameter in servlet? request.getAttribute does not work

Is it possible to have the same servlet perform validation? It seems that one might have to utilize some sort of recursion here, but when I type in something in the e-mail box and click submit the e-mail parameter is still blank.
After I click submit, the URL changes to: http://localhost/servlet/EmailServlet?Email=test
The page shows Email: null and the text box, but I was expecting it to go through the validation function (i.e. not be null). Is it possible to achieve this type of recursive behavior?
public class EmailServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String theForm =
"<FORM METHOD=\"GET\" ACTION=\"EmailServlet\">\n<INPUT TYPE=\"TEXT\" NAME=\"Email\"><P>\n"
+ "<INPUT TYPE=\"SUBMIT\">\n</FORM>";
String email = (String) request.getAttribute("Email");
// Bogus email validation...
if( email == null )
{
out.println("Email: " + email + "\n" + theForm);
}
else if(emailAddressNotBogous(email))
{
out.println("Thank you!");
}
else
{
out.println("“Invalid input. Please try again:\n" + theForm);
}
out.flush();
}
}
Update: as the accepted answer pointed out, there was an error in the code. Changing the getAttribute to getParameter fixes the "problem" :).
String email = (String) request.getAttributegetParameter("Email");
To get a form parameter in a servlet you use:
request.getParameter("Email");
And yes you can use the same servlet but it would be way easier to use two different servlets to do this.
you could have the form's method set to POST and then implement a doPost() method in your servlet. the doGet() will get called to display the form and the doPost() will get called to process the form submission.
alternatively you could have the doGet() method test for the presence of any parameters. if there aren't any then just display the form. if there are then process the submission...

Resources