Итак, я создал приложение, которое читает некоторые файлы gpx (файлы xml с координатами широты и долготы) и сохраняет эти точки в базе данных. Это веб-приложение, работающее на wildfly 10.1.0. Я загружаю файл и отправляю его в очередь, потому что процесс очень тяжелый.
Когда я делал тест на моей машине, у меня не было проблем. У меня больше оперативной памяти (16 ГБ), чем на моем сервере (8 ГБ), и на моем сервере запущено несколько приложений. У меня есть файл с 17 МБ, который, кажется, должен быть в состоянии справиться с этим, это не должно быть так сложно, но это приводит к тому, что моя бабочка падает на моем сервере. В моем ноутбуке он обрабатывает его меньше минуты.
Я не знаю, что я могу сделать лучше или что я могу сделать неправильно.
Это мой обработчик, он основан на этом
https://mappingdev.wordpress.com/2011/09/22/parsing-gpxxml-files-with-sax/
public class SAXFileHandler extends DefaultHandler {
private final static String NODE_WAYPOINT = "wpt"; //$NON-NLS-1$
private final static String NODE_TRACK = "trk"; //$NON-NLS-1$
private final static String NODE_TRACK_SEGMENT = "trkseg"; //$NON-NLS-1$
private final static String NODE_TRACK_POINT = "trkpt"; //$NON-NLS-1$
private final static String NODE_ROUTE = "rte"; //$NON-NLS-1$
private final static String NODE_ROUTE_POINT = "rtept"; //$NON-NLS-1$
private final static String NODE_NAME = "name"; //$NON-NLS-1$
private final static String NODE_TIME = "time"; //$NON-NLS-1$
private final static String NODE_ELEVATION = "ele"; //$NON-NLS-1$
private final static String NODE_SPEED = "speed"; //$NON-NLS-1$
private final static String NODE_DESCRIPTION = "desc"; //$NON-NLS-1$
private final static String ATTR_LONGITUDE = "lon"; //$NON-NLS-1$
private final static String ATTR_LATITUDE = "lat"; //$NON-NLS-1$
private List<GPXTrack> tracks;
private List<GPXPunto> wayPoints = new ArrayList<GPXPunto>();
// private List<GPXPunto> currentTrackPoints;
private GPXTrack currentTrack;
private GPXPunto currentTrackPoint;
private GPXPunto currentWayPoint;
private ZonedDateTime fechaExtraido;
private ZonedDateTime fechaIni;
private ZonedDateTime fechaFin;
private DateTimeFormatter parser = DateTimeFormatter
.ofPattern("[yyyy-MM-dd'T'HH:mm:ss.SSS'Z']" + "[yyyy-MM-dd'T'HH:mm:ss'Z']");
final StringBuilder mStringAccumulator = new StringBuilder();
public SAXFileHandler() {
super();
}
boolean mSuccess = true;
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
try {
if (name.equals(NODE_TRACK_POINT)) {
if (currentTrack != null) {
currentTrack.getPuntos().add(currentTrackPoint = new GPXPunto());
currentTrackPoint.setType(TipoPuntoEnum.TRKPT.toString());
handleLocation(currentTrackPoint, attributes);
}
} else if (name.equals(NODE_WAYPOINT)) {
currentWayPoint = new GPXPunto();
currentWayPoint.setType(TipoPuntoEnum.WPT.toString());
wayPoints.add(currentWayPoint);
handleLocation(currentWayPoint, attributes);
} else if (name.equals(NODE_TRACK)) {
currentTrack = new GPXTrack();
currentTrack.setPuntos(new ArrayList<GPXPunto>());
if (tracks == null)
tracks = new ArrayList<GPXTrack>();
tracks.add(currentTrack);
} else if (name.equals(NODE_TRACK_SEGMENT)) {
} else if (name.equals(NODE_ROUTE)) {
/* Agregar ruta algun rato */
} else if (name.equals(NODE_ROUTE_POINT)) {
/* Agregar punto para ruta algun rato */
}
} finally {
mStringAccumulator.setLength(0);
}
}
/**
* Processes new characters for the node content. The characters are simply
* stored, and will be processed when
* {@link #endElement(String, String, String)} is called.
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
mStringAccumulator.append(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if (NODE_TRACK_POINT.equals(name)) {
currentTrackPoint = null;
} else if (NODE_NAME.equals(name)) {
if (currentTrackPoint != null) {
currentTrackPoint.setPunto(mStringAccumulator.toString());
}else if (currentWayPoint != null) {
currentWayPoint.setPunto(mStringAccumulator.toString());
}else if (currentTrack != null && currentWayPoint == null && currentTrackPoint == null) {
currentTrack.setName(mStringAccumulator.toString());
}
} else if (NODE_TIME.equals(name)) {
if (currentTrackPoint != null) {
try {
/*
* Revisar acá si la fecha esta mal al importar
*/
LocalDateTime ldt = LocalDateTime.parse(mStringAccumulator.toString(), parser);
ZoneId zoneId = ZoneId.of( "UTC" ); // Or "America/Montreal" etc.
ZonedDateTime zdt = ldt.atZone( zoneId );
currentTrackPoint.setFecha(zdt);
/// ZonedDateTime.parse(mStringAccumulator.toString(), parser);
fechaFin = currentTrackPoint.getFecha();
if (fechaIni == null)
fechaIni = currentTrackPoint.getFecha();
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
} else if (currentWayPoint != null) {
LocalDateTime ldt = LocalDateTime.parse(mStringAccumulator.toString(), parser);
ZoneId zoneId = ZoneId.of( "UTC" ); // Or "America/Montreal" etc.
ZonedDateTime zdt = ldt.atZone( zoneId );
currentWayPoint.setFecha(zdt);
} else if (tracks == null || tracks.size() == 0) {
LocalDateTime ldt = LocalDateTime.parse(mStringAccumulator.toString(), parser);
ZoneId zoneId = ZoneId.of( "UTC" ); // Or "America/Montreal" etc.
ZonedDateTime zdt = ldt.atZone( zoneId );
fechaExtraido = zdt;
}
} else if (NODE_ELEVATION.equals(name)) {
if (currentTrackPoint != null) {
currentTrackPoint.setEle(Double.parseDouble(mStringAccumulator.toString()));
} else if (currentWayPoint != null) {
currentWayPoint.setEle(Double.parseDouble(mStringAccumulator.toString()));
}
} else if (NODE_SPEED.equals(name)) {
if (currentTrackPoint != null) {
currentTrackPoint.setDesc(mStringAccumulator.toString());
try {
currentTrackPoint.setVelocidad(Double.parseDouble(mStringAccumulator.toString()));
} catch (NumberFormatException e) {
// wrong data, do nothing.
}
}
} else if (NODE_DESCRIPTION.equals(name)) {
if (currentWayPoint != null) {
currentWayPoint.setDesc(mStringAccumulator.toString());
}
} else if (NODE_WAYPOINT.equals(name)) {
currentWayPoint = null;
} else if (NODE_TRACK.equals(name)) {
currentTrack = null;
} else if (NODE_TRACK_SEGMENT.equals(name)) {
} else if (NODE_ROUTE.equals(name)) {
} else if (NODE_ROUTE_POINT.equals(name)) {
}
}
@Override
public void error(SAXParseException e) throws SAXException {
mSuccess = false;
}
@Override
public void fatalError(SAXParseException e) throws SAXException {
mSuccess = false;
}
/**
* Handles the location attributes and store them into a
* {@link LocationPoint}.
*
* @param locationNode
* the {@link LocationPoint} to receive the location data.
* @param attributes
* the attributes from the XML node.
*/
private void handleLocation(GPXPunto gpxPunto, Attributes attributes) {
try {
double longitude = Double.parseDouble(attributes.getValue(ATTR_LONGITUDE));
double latitude = Double.parseDouble(attributes.getValue(ATTR_LATITUDE));
gpxPunto.setLon(longitude);
gpxPunto.setLat(latitude);
} catch (NumberFormatException e) {
// wrong data, do nothing.
}
}
public List<GPXTrack> getTracks() {
return tracks;
}
public void setTracks(List<GPXTrack> tracks) {
this.tracks = tracks;
}
public List<GPXPunto> getWayPoints() {
return wayPoints;
}
public void setWayPoints(List<GPXPunto> wayPoints) {
this.wayPoints = wayPoints;
}
public GPXTrack getCurrentTrack() {
return currentTrack;
}
public void setCurrentTrack(GPXTrack currentTrack) {
this.currentTrack = currentTrack;
}
public GPXPunto getCurrentTrackPoint() {
return currentTrackPoint;
}
public void setCurrentTrackPoint(GPXPunto currentTrackPoint) {
this.currentTrackPoint = currentTrackPoint;
}
public GPXPunto getCurrentWayPoint() {
return currentWayPoint;
}
public void setCurrentWayPoint(GPXPunto currentWayPoint) {
this.currentWayPoint = currentWayPoint;
}
public ZonedDateTime getFechaExtraido() {
return fechaExtraido;
}
public void setFechaExtraido(ZonedDateTime fechaExtraido) {
this.fechaExtraido = fechaExtraido;
}
public ZonedDateTime getFechaIni() {
return fechaIni;
}
public void setFechaIni(ZonedDateTime fechaIni) {
this.fechaIni = fechaIni;
}
public ZonedDateTime getFechaFin() {
return fechaFin;
}
public void setFechaFin(ZonedDateTime fechaFin) {
this.fechaFin = fechaFin;
}
public DateTimeFormatter getParser() {
return parser;
}
public void setParser(DateTimeFormatter parser) {
this.parser = parser;
}
public static String getNodeElevation() {
return NODE_ELEVATION;
}
public static String getNodeDescription() {
return NODE_DESCRIPTION;
}
public static String getAttrLongitude() {
return ATTR_LONGITUDE;
}
public static String getAttrLatitude() {
return ATTR_LATITUDE;
}
}