1

I have a hard time understanding on how to user MVC pattern in my java based web application.

I have multiple tables (postgreSQL 9.4) and the data stored there is going to be visible to multiple users.

As far as my understanding goes I need a Model (which holds all data from the DB tables) and any user who wants to view any of this data uses a view to do so.

Right now I have a class that is full of getter methods. Each of those asks the database to provide the stored data from a specific sql table. That data is then retured as a json String into my .jsp page and there I fill this data into a html table (.jsp just hols the table construct)

This is sort of a model, except the fact that data is just pulled from the db and given to the jsp to display.

From there on, how can I assure that all users always have the same view on the data and data is always up to date even when user A makes changes to the data that other users are also looking at??

As I have multiple db tables do I need a model for each table?

EDIT: The way I would approach this issue would be the following.

  • I have a class (model) for each database table.
  • On Application startup I pull the data from the SQL table and store it inside the specific class
  • If any user wants to view data I have a getter Method in each model class to send this data to the .jsp page for display
  • If any user does changes to the database (setter method) the data is (after the set method is executed) pulled again so the model is up to date
  • Then I somehow need the data that is viewed by any user is updated on the .jsp page

Is this going in the same direction as MVC pattern?

EDIT1:

An example

One of my SQL tables looks like this

CREATE TABLE users
(
  id serial NOT NULL,
  user character varying(50) NOT NULL,
  CONSTRAINT users_pkey PRIMARY KEY (id)
)

My Model class looks like this:

public class Users extends HttpServlet implements Servlet{
    private List<List<String>> users = new ArrayList<List<String>>();

    private void load_userData(){
        // Code to pull data from database
        /**/

        List<List<String>> users = new ArrayList<List<String>>(2);
        // instantiate array list
        users.add(new ArrayList<String>());
        users.add(new ArrayList<String>());

        try {
            m_ResultSet = database_connection.execute_querry_on_db(query);
            while (m_ResultSet.next()) {
                users.get(0).add(m_ResultSet.getString("id"));
                users.get(1).add(m_ResultSet.getString("user"));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
        }
        // store pulled data into model
        this.users = users ;
    }

    private List<List<String>> get_userData(){
        // Code to pull data from Model
        return users;
    }

    private void set_userData(){
        // make changes to SQL table with an update/insert query

        // Update Model with new data since it has been altered
        get_userData();
    }


    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String requested_values = request.getParameter("type");

        if("get_users".equals(requested_values)){
            String json_users = new Gson().toJson(get_userData());

            // write JSON string to response
            response.getWriter().write(json_users);
        }
    }

}

This way the model is always up to date with the actual data from the database.

Since there is model & controller in the same class a possible controller would look like the one below??

Because using a controller like this I have to some "initialisation" in a main area of my code I guess, but that is not clear to me..

public class User_Controller extends HttpServlet implements Servlet{
    private User_data model;


    public OE_Controller(User_data model){
        this.model = model;
   }

    private List<List<String>> get_userData(){
        return model.users;
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String requested_values = request.getParameter("type");

        if("get_users".equals(requested_values)){
            String json_users = new Gson().toJson(get_userData());

            // write JSON string to response
            response.getWriter().write(json_users);
        }
    }

}

####### Solution to MVC-"Problem" ####### What do you think about this solution? (as the controller will hand out data directly, instead of calling a method from "main")

Users.java (Model)

public class Users{
    private List<List<String>> users = new ArrayList<List<String>>();

    public List<List<String>> get_users(){
        return users;
    }

    // Fill model with data from database
    public void pull_UserData(){
        /**/
        List<List<String>> users = new ArrayList<List<String>>(2);
        // instantiate array list
        users.add(new ArrayList<String>());
        users.add(new ArrayList<String>());

        try {
            m_ResultSet = database_connection.execute_querry_on_db(query);
            while (m_ResultSet.next()) {
                users.get(0).add(m_ResultSet.getString("id"));
                users.get(1).add(m_ResultSet.getString("user"));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
        }
        /**/
        this.users = users;
    }
}

User_Controller.java (Controller)

public class User_Controller extends HttpServlet implements Servlet{
    private Users model;


    public User_Controller(Users model){
        this.model = model;
    }

    public List<List<String>> get_users(){
        return model.get_users();
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String requested_values = request.getParameter("type");

        if("get_users".equals(requested_values)){
            String json_users = new Gson().toJson(get_users());

            // write JSON string to response
            response.getWriter().write(json_users);
        }
    }
}

"MAIN"

// create Model
Users model = pull_UserData();

// create Controller
User_Controller controller = new User_Controller(model);

// get Model data
controller.get_oes();
// Even though I will never access Model data from here since
// my Controller will hand out the data via the do_Get() method
// "Main" is just to load the model data once on application startup
// and the model data reload is done after a setter method is executed

public static Users fill_model_Users_data(){
    Users users = new Users();
    users.pull_UserData();
    return users;
}

What is left is to have the data always updated on all session in the frontend.

So each user of my application needs to see the same data. Here I would need a listener that refreshes the .jsp page when another user does changes to the database. How would I do this??

EDIT: I found some solutions working with a time interval to check for new data but that still leaves me with the problem that there is a data mismatch based on how long the timer interval is & setting the interval to 1ms for example cannot be the optimal solution I guess (there has to be a "smoother" way to do that)

I'd rather have the application to update the .jsp page with new data as soon as there is new data available & even then I'm left with the Race-Condition which user is faster in clicking a button to lets say delete a user (one will succeed & one will fail)

Alkahna
  • 441
  • 7
  • 21
  • 1
    I wouldn't pull the data on startup. You should pull it when you need it. – kukudas Dec 15 '15 at 09:01
  • either way works, since there is a lot of data I would like to have it available on startup. That way there is less datapulling done when data is requested. – Alkahna Dec 15 '15 at 09:33

2 Answers2

2

You do not use a controller for communication between model and view as far as I see that. So it's not really MVC.

It is not necessary to have a model for each table, but it is recommended.

The idea itself seems to be solid.

To be more specific: I have often seen and used the following structures: controller, services and models. The models save the data whereas the services are responsible for pulling it once the user sends a request. The request is handled via the controller, which informs the corresponding service to pull the data and provides the necessary models to the view.

A short example I found (Hibernate/Spring MVC)

UserController (manages all incoming requests and communicates with UserService):

@RequestMapping(value = "user/{id}", method = RequestMethod.GET)
@ResponseBody
public User get(@PathVariable Long id, Locale locale, Model model) throws NotFoundException {   
    User u = userService.find(id);
    if (u != null)
        return u;
    else
        throw new NotFoundException("user not found");
}

@RequestMapping(value = "user", method = RequestMethod.GET)
@ResponseBody
public List<User> list(Locale locale, Model model) {
    List<User> l = userService.list();  
    return l;
}

UserService (takes care of providing the right data for the controller):

public User find(Long key) {
    // access on database 
    return (User) sessionFactory.getCurrentSession().get(User.class, key);
}

public List<User> list() {
    // again query the database for a list but not for a single user
    // the DAO is just something hibernate specific
    return userDAO.list();
}

And then at last there is a class User which is used for communication to the interface (and contains all necessary attributes) - in this example it was used to pass via REST/JSON.

LordAnomander
  • 1,103
  • 6
  • 16
  • MVC without C, sounds interesting^^ I updated my question with code of a model I just made. That should work for my case but is still missing something to update the frontend page that the users of my application are viewing – Alkahna Dec 15 '15 at 09:35
  • 1
    [Previous Question](http://stackoverflow.com/questions/10774446/auto-refresh-jsp-page-when-data-changes) < Maybe this can help you to solve your problem. Also it is somewhat a bad design with what you have in your model. If you want a MVC you should move `doGet()` in a controller class. :) – LordAnomander Dec 15 '15 at 09:54
  • will take a look at the other Question you linked. So I have Model & Controller combined right now? How would such a Controller class look like, can you provide an example? – Alkahna Dec 15 '15 at 09:59
  • Basically a controller contains the handling of all requests you get from the view (you would call that controller of yours `UserController` for instance and you might have another controller for a different view/model and so on). I'm a little spoiled by using Hibernate and Spring MVC, so it's tough for me to come up with any examples ;) – LordAnomander Dec 15 '15 at 10:06
  • An example using Spring/Hibernate(dont know this up to now) would work as well ;) Looking at the question you linked gives 2 options which A)refreshes data when the page is reloaded by the user or B) a timer that checks from time to time. To Solution B: A Timer would work but the interval has to be very small to ensure data is always up to date. To Solution A: to update the data when the pages reloads is not the problem at all. – Alkahna Dec 15 '15 at 10:08
  • I added code for a possible controller but now that controller has to be initialized somehow, how do I do that? – Alkahna Dec 15 '15 at 10:45
  • Yes, without spring you need to declare the controller in your main class, see also [this link](http://stackoverflow.com/questions/5217611/the-mvc-pattern-and-swing). – LordAnomander Dec 15 '15 at 10:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97960/discussion-between-alkahna-and-tbrown). – Alkahna Dec 15 '15 at 11:01
1

To ensure that the JSP page always shows the latest data, page has to be refreshed using javascript or ajax.

Srivignesh
  • 337
  • 3
  • 14
  • I would need a listener in that .jsp pages that knows when the model has been updated? I only used a listener once and that was ín pure java code – Alkahna Dec 15 '15 at 09:37
  • jquery and ajax provides options to set some interval based on which, requests can be frequently sent to the backend to obtain latest model values. Following link can be referred. http://crunchify.com/how-to-use-ajax-jquery-in-spring-web-mvc-jsp-example/ – Srivignesh Dec 15 '15 at 11:48
  • yeah I read about that as well but I rather like some notification pushed to the clients browser that the model has been updated (altered data/new data) and it refreshes the moment new data is available. Since intervals still leave me with the problem that there is a data mismatch baed on interval length – Alkahna Dec 15 '15 at 12:31
  • 1
    well... I understand your requirement. You can try learning web socket or atmosphere.js for this. I don't have complete knowledge on them. – Srivignesh Dec 16 '15 at 04:51
  • I heard about atmosphere.js before. I will have a look at that framework, thanks – Alkahna Dec 16 '15 at 08:11