2

I currently have a basic j2ee website. Currently, a jsp frontend gets data from the backend (the java program, lets call it object "Score"). The backend gets this data from a web site.

<% Main m = new Main(5); %>
<table style="width: 100%">
  <tr>
    <th align="left">NBA</th>
    <th style="text-align: right"><%=m.getTime("nba")%></th>
  </tr>
</table>
<% Iterator itrNba = m.getNbaM().entrySet().iterator();
   for (Map.Entry<Integer, Match> entry : m.getNbaM().entrySet()) {
     Match value = entry.getValue(); %>

However, this only happens once. If the user wants new data, they have to refresh the page, the backend will run the algorithm to populate some objects (HashMaps), and the jsp displays the values.

The backend data is sports scores and I want this to be a live feed. Therefore I have to make the back end poll the source, and the front end poll the backend (not necessarily the same intervals either).

How can I make my data objects persist? With my current implementation, every time the page is loaded, a new Score, when Score should be the same for all clients (the frontend jsp). So I made my data objects static and I put the main entry point in a loop, and it isnt working.

Im thinking my main java Scores object needs to be run as a service. Do I need to use servlets here?

Is there an easy way to accomplish what I'm describing?

migrated from stackoverflow.com Dec 1 '14 at 8:23

This question came from our site for professional and enthusiast programmers.

  • Specifically, how does the jsp get the data from the backend? Could you include that part of the code? – user40980 Nov 30 '14 at 22:20
  • I use scriplets and just write getters for the Score object. It iterates through a hashmap – Allen Nov 30 '14 at 23:02
  • You can edit a post to include additional information (the links are under the tags - share, edit, flag, delete). Selecting the code and then clicking the {} button will then format it as a code block (multiline selects get indented four spaces and become syntax highlighted; in line selections use the backquote and show up like this). – user40980 Dec 1 '14 at 0:19
  • Is there a way for me to make another class to access a looping main class? – Allen Dec 1 '14 at 3:22
  • 1
    Does the solution have to be in Java? If it where me, I'd be tempted to just statically pull the scores feed, spit it out as a JSON list over a regular HTTP request, then consume said data in the webpage using JavaScript. Doing that means you potentially have millions of ways of doing it. – shawty Dec 1 '14 at 17:18
1

So, lets think about how the current approach works.

  1. You've got a jsp that is invoked
  2. It creates a Main object.
  3. The Main object goes out and does some work and provides this information via its fields or method after control has returned.
  4. The jsp accesses these fields or methods and presents them to the end user.

This has a number of issues with scalability that you're seeing. You could be doing what appears to be a denial of service on the target site of the data. Thats not good (though that said, they've probably got better caching and network than you do - still, it isn't good). The work that you do on your own system isn't shared between requests and so every request has to do the work again (even if nothing is changed).

There are two parts to this application, and as written there is a clear separation between the two. That makes things a little bit easier.


If this is transient data (you don't need to persist it for more than a short period of time), the easiest thing to do would be to store it in the Context. There are several contexts available - Application (all of Tomcat), Servlet (that servlet's info), Session (one user's session info), and Request (note: this is framework dependent - you've got things like Spring, PrimeFaces, or your own ad hoc).

Now, I'm going to start out with you could do it this way, but its a way that is rather... undisciplined. The lack of discipline may make it easier to implement now, but harder to extend properly later. So make sure you keep reading after seeing the "it could be done this way".

You could create an object that conforms to the JavaBeans naming standards that has the data and the timestamp (for caching) and stick it in the application context.

It would look something like:

package com.mycompany;

public class MyBean {

  private Date date;
  private int score;

  public Date getDate() { return date;  }
  public void setDate(Date arg) {  date = arg; }
  public int getScore() { return score;  }
  public void setScore(int arg) { score = arg; }
}

Register it as part of the context of the application in web.xml and then have Main look it up, check to see if it needs to fetch new data or not, and if so, fetch the data from remote and store the data in the bean. A bit more of this spelled out in Tomcat Standard Resource Factories in the Tomcat docs. Essentially, you are creating a Singleton that you can access. I'm not going to say that this is a good approach, but it will work.

The thing is, thats kind of ugly. Yea, you can store the data there, but its still kind of ugly. You shouldn't have any problem with a simple class like the one described, but if you have something more complex, its possible to get race conditions where two requests both decide that they want to fetch the data and each store part of the data which is mismatched.

This also really doesn't scale. If you have two servers (for redundancy) you could get one with the data from 10 minutes ago and one from 5 minutes ago. And you hit the page and you get one answer, then you hit it again and you get another answer, and then you hit it again and you get the first answer. With game scores, this could be very confusing.


And here's where I'm going to start getting architect astronauty.

You need to have the data somewhere. Put it in a database. It could be a classic relational one like MySQL; or if the data fits the appropriate model, a NoSQL database of some sort might be appropriate. The specifics of which NoSQL database would be the right one depends significantly on the type of data you are storing and how you want to access it (and remember, if you are dealing with multiple databases for redundancy, the eventual consistency of some flavors of NoSQL can bite you hard).

So, you've got a database. You also have a process that runs outside of the Tomcat container that puts the information in it. This could be a quick script or its own Java application. Its just fetching data from some source and reshaping it to fit in the correct database. It runs once a minute or so (depending on what your needs are). Thats all, it fetches data, and puts it in the database.

Now, instead of Main fetching the data from the site, it fetches the data from the database. This is fast. Frankly, you shouldn't be doing it from a separate class at this point - just fetch the data. It also fetches a complete record when it does so that you don't get race conditions in there.

You could stick it right in the JSP, though thats seen as rather ugly. I'll tell you up front that this offends my sensibilities.

What you've got right now is a model 1 application. It works, and its easy to write and deploy. But it mixes the business and presentation logic in the JSP. You've also got very limited sharing of code between JSPs which means there is lots of potential code duplication which makes maintain a mess.

You really should look at a model 2 approach which has a servlet handling the 'traffic cop' aspect of the web application, a data access layer that fetches the data from some data source, and the jsp that gets the request from the servlet, pulls out the appropriate info stored in beans and uses Expression Language (often written EL) instead of scriptlets in the jsp.

Yes, this is a bit more ceremony in creating it. However it's a well known and standardized model that another Java programmer could come in and immediately recognize and build on with less work. It also makes it feasible to test small parts of it to make sure it all still works (JSPs are notoriously difficult to unit test).

You could do this with straight up servlets (which is quite doable), or look at using a framework such as Spring, Stripes, or Play to make it easier to work with. The frameworks put a structure around the code and how it is written - adding some discipline to the layout and enforcing it to ultimately make a higher quality product.

  • Thank you very much for the long and detailed post. You are 100% correct in that my current approach is very basic. I will take your advice and try to transform my "model 1" into a "model 2" design right away. I was kind of stuck and had some rough ideas of where to go, but you just gave me a road map. I will be constantly referring back to your suggestions and advice, so once again, your thorough response is very appreciated! Allen – Allen Dec 1 '14 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.