Мне нужно извлечь данные из файла CSV, который находится на моем компьютере, и распечатать их на веб-странице через сервлет. Данные должны читать по одной строке за раз и обновляться каждую секунду, а затем, когда они попадают в конец файла CSV, начать снова с верха. Я чувствую, что я близко, но когда я пытаюсь собрать программу, ничего не выводится на веб-страницу. Вполне возможно, что что-то не так в коде. Буду очень признателен за любую помощь, я полностью отстой в программировании и просто пытаюсь пройти через этот класс. Я добавил код из всех 3 частей. Я использую NetBeans IDE 8.2 и сервер Glassfish.
main.xthml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ivan's HTTP ETF</title>
<link rel="stylesheet" type="text/css" href="resources/css/default.css" />
<script type="text/javascript">
var ajaxRequest;
function updatePage() {
if (ajaxRequest.readyState === 4) {
var arraypv = ajaxRequest.responseText.split("/");
document.getElementById("date").innerHTML = arraypv[0];
document.getElementById("time").innerHTML = arraypv[1];
document.getElementById("price").innerHTML = arraypv[2];
document.getElementById("volume").innerHTML = arraypv[3];
document.getElementById("52-weekHigh").innerHTML = arraypv[4];
document.getElementById("52-weekLow").innerHTML = arraypv[5];
makeAjaxRequest();
}
}
function makeAjaxRequest() {
ajaxRequest = new XMLHttpRequest();
ajaxRequest.onreadystatechange = updatePage;
ajaxRequest.open("GET", "http://localhost:8080/dukeetf/dukeetf", true);
ajaxRequest.send(null);
}
</script>
</head>
<body onload="makeAjaxRequest();">
<h1>Ivan's HTTP ETF</h1>
<table>
<tr>
<td align="left">Ticker</td>
<td align="right">IGH</td>
</tr>
<tr>
<td align="left">Date</td>
<td id="date" align="right">--</td>
</tr>
<tr>
<td align="left">Time</td>
<td id="time" align="right">--</td>
</tr>
<tr>
<td align="left">Price</td>
<td id="price" align="right">--</td>
</tr>
<tr>
<td align="left">Volume</td>
<td id="volume" align="right">--</td>
</tr>
<tr>
<td align="left">52-weekHigh</td>
<td id="weekHigh" align="right">--</td>
</tr>
<tr>
<td align="left">52-weekLow</td>
<td id="weekLow" align="right">--</td>
</tr>
</table>
</body>
</html>
DukeETFServlet.java:
package javaeetutorial.web.dukeetf;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns={"/dukeetf"}, asyncSupported=true)
public class DukeETFServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger("DukeETFServlet");
private static final long serialVersionUID = 2114153638027156979L;
private Queue<AsyncContext> requestQueue;
@EJB private PriceVolumeBean pvbean;
@Override
public void init(ServletConfig config) {
/* Queue for requests */
requestQueue = new ConcurrentLinkedQueue<>();
/* Register with the bean that provides price/volume updates */
pvbean.registerServlet(this);
}
/* PriceVolumeBean calls this method every second to send updates */
public void send(String date, String time, String price, String volume, String weekHigh, String weekLow) {
/* Send update to all connected clients */
requestQueue.forEach((acontext) -> {
try {
String msg = String.format(date, time, price, volume, weekHigh, weekLow);
PrintWriter writer = acontext.getResponse().getWriter();
writer.write(msg);
logger.log(Level.INFO, "Sent: {0}", msg);
/* Close the connection
* The client (JavaScript) makes a new one instantly */
acontext.complete();
} catch (IOException ex) {
logger.log(Level.INFO, ex.toString());
}
});
}
/* Service method */
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html");
/* Put request in async mode. */
final AsyncContext acontext = request.startAsync();
/* Remove from the queue when done */
acontext.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection closed.");
}
@Override
public void onTimeout(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection timeout.");
}
@Override
public void onError(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection error.");
}
@Override
public void onStartAsync(AsyncEvent ae) throws IOException { }
});
/* Add to the queue */
requestQueue.add(acontext);
logger.log(Level.INFO, "Connection open.");
}
}
PriceVolumeBean.java:
package javaeetutorial.web.dukeetf;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/* Updates price and volume information every second */
@Startup
@Singleton
public class PriceVolumeBean {
private static final Logger logger = Logger.getLogger("PriceVolumeBean");
private final String csvFile = "/Users/ivanhurdimac/glassfish5/docs/javaee-tutorial/examples/web/servlet/dukeetf/project4input.csv";
/* Use the container's timer service */
@Resource TimerService tservice;
private BufferedReader reader = null;
private DukeETFServlet servlet;
@PostConstruct
public void init() {
try {
reader = new BufferedReader(new FileReader(csvFile));
} catch (IOException e) {
throw new RuntimeException("Failed to read the CSV file [" + csvFile + "].", e);
}
/* Intialize the EJB and create a timer */
logger.log(Level.INFO, "Initializing EJB.");
tservice.createIntervalTimer(1000, 1000, new TimerConfig());
}
public void registerServlet(DukeETFServlet servlet) {
/* Associate a servlet to send updates to */
this.servlet = servlet;
}
@Timeout
public void timeout() {
String line;
try {
line = reader.readLine();
// Once we are done, just return
if (line == null) {
return;
}
} catch (IOException e) {
throw new RuntimeException("Failed to read a line from the CSV file [" + csvFile + "].", e);
} finally {
if (reader != null){
try{
reader.close();
}catch (IOException e){
throw new RuntimeException("CSV file didn't close [" + csvFile + "].", e);
}
}
}
String[] parts = line.split(",");
/* Adjust price and volume and send updates */
String date = parts[0];
String time = parts[1];
String price = parts[2];
String volume = parts[3];
String weekHigh = parts[4];
String weekLow = parts[5];
if (servlet != null) {
servlet.send(date, time, price, volume, weekHigh, weekLow);
}
}
}