0

continuing my studies... I'm trying to write some data into a txt file but I'm receiving this exception. I'm using Tomcat 7.0. The EmailList.txt is in the folder, so I don't know what is going one. Can you guys please, help me

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>AddToEmailListServlet</servlet-name>
        <servlet-class>email.AddToEmailListServlet</servlet-class>
        <init-param>
            <param-name>relativePathToFile</param-name>
            <param-value>/WEB-INF/EmailList.txt</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>AddToEmailListServlet</servlet-name>
        <url-pattern>/addToEmailList</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>join_email_list.jsp</welcome-file>
    </welcome-file-list>
</web-app>

servlet class This class is going to process the data.

package email;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import business.User;
import data.UserIO;

public class AddToEmailListServlet extends HttpServlet
{   @Override 
    protected void doPost(HttpServletRequest request, 
                          HttpServletResponse response) 
                          throws ServletException, IOException
    {
        // get parameters from the request
        String firstName = request.getParameter("firstName");
        String lastName = request.getParameter("lastName");
        String emailAddress = request.getParameter("emailAddress");

        User user = new User(firstName, lastName, emailAddress);

       //validation
        String message = "";
        String url = "";
        if (firstName.length() == 0 || lastName.length() == 0 || emailAddress.length() == 0) {
            message = "Please fill out all three boxes";
            url = "/join_email_list.jsp";
        }else{
            message = "";
            ServletConfig config = getServletConfig();
            String relativePath = config.getInitParameter("relativePathToFile");
            UserIO.addRecord(user, relativePath);
            url = "/display_email_entry.jsp";
        }
        request.setAttribute("user", user);
        request.setAttribute("message", message);

        //forward request and response

        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
        dispatcher.forward(request, response);             
    }    
}

The I/O class

package data;

import java.io.; import java.util.;

import business.User;

public class UserIO
{
    public static void addRecord(User user, String filename) throws IOException
    {
        File file = new File(filename);
        PrintWriter out = new PrintWriter(
                new BufferedWriter(new FileWriter(file)));
        out.println(user.getEmailAddress()+ "|"
                + user.getFirstName() + "|"
                + user.getLastName());        
        out.close();
    }
}
Camus
  • 827
  • 2
  • 20
  • 36

1 Answers1

0

The problem is in the code behind UserIO#addRecord() method which you didn't show in your question at all, so it's hard to pinpoint the root cause. But I gather that you just did a new File() on the given relative path. This is a bad idea and well due to the following reasons:

  • The new File() operates relative to the current working folder in the disk file system, not to the webapp folder structure. Even then, the leading slash / makes it relative to the disk root.
  • The WAR is not necessarily expanded on disk, it can also be expanded in memory insteaad, there's then no means of any valid disk file system path which you could use in new File().
  • When the WAR is redeployed or even when the server restarts, all changes in the expanded WAR folder are lost because they are not present in the original WAR file.

Rather write to a file on an absolute path somewhere outside the expanded WAR folder, or use a database instead.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the advise. But I'm following a book, I will get to database access in the next few chapters. One thing that I've noticed is all the changes that I make in the web.xml does not work. I created a custom 404 error page. When the error occurs Tomcat loads its default page. Do you know whether can be a configuration or something else? Cheers – Camus Dec 13 '11 at 01:27
  • You need to restart Tomcat after every `web.xml` change or to configure it to turn on hotdeployment so that it will automatically restart the webapp when a change in `web.xml` is made. If that doesn't solve it, then you probably didn't understood the servlet exception handling properly. This is a whole subject at its own, so here's, just a link: http://stackoverflow.com/questions/5299169/how-does-tomcat-prioritize-which-type-of-error-page-to-use If you still stucks, just ask a new question. This is offtopic. – BalusC Dec 13 '11 at 01:32
  • Thanks again. I'll have a look on this link later. I already restarted Tomcat but it doesn't work. The funny thing is that the book provide the code, so I don't know whether could be a compatibility problem with Tomcat. The Tomcat that the book uses is version 6 and I'm using the newest version. Anyway I have a look on this link and if I don't get it working I ask again. Thanks – Camus Dec 13 '11 at 06:33
  • Hi, I just upload the I/O class. I'm still stuck. I'm not receiving any exception but no data is being written in the file. I change the location of the file to the root directory of the application but it is still not working. As I ask in another topic, any change that I'm doing on the web.xml file is not working as well. For example if I create a custom 404 error page, it doesn't appear that page when the error occurs, but if I don't use a correct statement in this file Tomcat lunch a error. Any idea? – Camus Dec 13 '11 at 23:05
  • As answered, the `File` operates relative to the working directory of the current disk (e.g. `Tomcat/bin` or something). The leading slash in the path makes it relative to disk root. So using `new File("/WEB-INF/foo.txt")` would write to `C:\WEB-INF\foo.txt`. You should not attempt to write to the expanded WAR folder, but to an **absolute** path on the disk file system. You should write to something like `/var/webapp/data/EmailList.txt` and make sure that those folders exist on the same disk partition as where the server is installed. – BalusC Dec 13 '11 at 23:21
  • Thanks man, it is working now. Do you know why it wasn't working? And do you hava any idea about the web.xml issue? Cheers – Camus Dec 13 '11 at 23:50
  • I have already answered why it didn't work. You misunderstood how `File` works and the concept of relative/absolute paths. Did you *understand* my answer in any way? What parts exactly is unclear to you? – BalusC Dec 13 '11 at 23:56
  • So if I want to use i .txt inside the application. What should I use. It's not really clear to me. What if I have an application called Test One and I have a file inside WEB-INF. How can access it? – Camus Dec 17 '11 at 15:58
  • You can *read* it by obtaining the `InputStream` from `ServletContext#getResourceAsStream()`. But you can not *write* to it. If you want to write to a file, you have to write it to a fixed path outside the webapp context (for reasons as already answered). – BalusC Dec 17 '11 at 16:02
  • Ok I think I got it. Is this principle works for the url-pattern. Because the jsp's and html's page will be inside the war folder, so how can I change the url displayed on the browser? – Camus Dec 18 '11 at 04:22
  • Either create a `Filter` which forwards to the desired resource based on some URL rewrite configuration or maybe create a servlet which follows the front controller design pattern with RESTful-like URLs. There's an existing filter out: http://www.tuckey.org/urlrewrite/ As to the servlet, check http://stackoverflow.com/questions/3541077/design-patterns-web-based-applications/3542297#3542297 – BalusC Dec 18 '11 at 15:32