Java WebApp不断返回相同的结果

问题描述 投票:0回答:2

我编写了这个Web应用程序,在输入城市坐标(纬度,经度)(来源:json)后,该列表返回了美国发生的10次最近地震的列表。现在,我有2个问题:

问题1。

  1. 我输入了所选城市(例如,西雅图)的坐标,并且得到了正确的结果。
  2. 我输入第二个城市的坐标(例如,华盛顿特区),我得到不同的(正确的)结果。
  3. 我在第一个城市(例如,西雅图)输入了相同的坐标,结果与之前的第二个搜索相同。
  4. 我输入第三,第四,第六等城市的坐标,并且得到相同的结果。

这就像应用程序被卡住了(经过2-3次正确的查询后?)。有时我会连续获得三个不同的结果,有时会得到四个,有时只会打印两个,后来又打印出相同的结果。如果我将坐标硬编码到Servlet到Java方法中,则每次的结果都不相同,因此我猜测将输入字段传递到Java方法中会遇到一些问题。我从列表中选择城市还是自己输入坐标都没关系。

问题2。

  1. 我从下拉列表中选择一个城市。
  2. 正在将坐标输入到输入html表单中,例如堪萨斯城:纬度:39.099728经度-94.578568。
  3. 我在纬度上添加字母/符号,例如39.099728sdjfhjsdf,经度:-94.578568 我按提交
  4. 我得到该字段格式不正确的信息(到现在为止还可以)。
  5. 我从下拉列表中选择了另一个城市,输入字段被新的坐标填充,然后按提交,但是我不断收到警告,提示数字格式不正确(即使输入的是new仍会读取39.099728sdjfhjsdf)。

这里是最小的工作示例。项目是用Eclipse写的。

ReadLongitudeAndLatitudeServlet.java

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dominikazb.earthquakes.engine.ReadJsonFile;

@WebServlet("/read")
public class ReadLongitudeAndLatitudeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String latitudeOfSearchedCityString = request.getParameter("latitudeOfSearchedCity");
    String longitudeOfSearchedCityString = request.getParameter("longitudeOfSearchedCity");
    ReadJsonFile.getReadJson().convertJsonToJavaObjects(latitudeOfSearchedCityString, longitudeOfSearchedCityString);
    response.sendRedirect("list");
}
}

PrintEarthquakesServlet.java

import java.io.IOException;
import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dominikazb.earthquakes.engine.ReadJsonFile;

@WebServlet("/list")
public class PrintEarthquakesServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    TreeMap<Double, String> outputMap = ReadJsonFile.getReadJson().read10closestCities();
    request.setAttribute("outputMap", outputMap);
    request.getRequestDispatcher("/earthquakesList.jsp").forward(request, response);
}
}

ReadJsonFile.java

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ReadJsonFile {

    private static ReadJsonFile readJson = new ReadJsonFile();  
    private static String place;
    private static double longitude;
    private static double latitude; 
    private Map<Double, String> distanceAndPlaceMapForAllCities = new TreeMap<>();
    private HarvesineFormula harvesine = new HarvesineFormula();

public static ReadJsonFile getReadJson() {
    return readJson;
}


@SuppressWarnings("unchecked")
public void convertJsonToJavaObjects(String latitudeOfSearchedCity, String longitudeOfSearchedCity) throws IOException, JsonParseException {

    ObjectMapper om = new ObjectMapper();               
    om.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); //ignore fields that are not formatted properly
    TypeReference<HashMap<Object,Object>> typeRef = new TypeReference<HashMap<Object,Object>>() {};
    HashMap<Object, Object> resultMap = om.readValue(new URL("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson"), typeRef);

    ArrayList<Object> featuresArrayList = (ArrayList<Object>) resultMap.get("features");

    for(Object o : featuresArrayList) {
        try {
            LinkedHashMap<Object, Object> featuresLinkedHashMapInside = (LinkedHashMap<Object, Object>) o;
            Map<Object, Object> newMapping = (Map<Object, Object>) featuresLinkedHashMapInside.get("properties");
            place = newMapping.get("place").toString();
            Map<Object, Object> geometryMap = (Map<Object, Object>) featuresLinkedHashMapInside.get("geometry");
            ArrayList<Object> coordinatesArrayList = (ArrayList<Object>) geometryMap.get("coordinates");            
            longitude = (double) coordinatesArrayList.get(0);
            latitude = (double) coordinatesArrayList.get(1);

            double latitudeOfSearchedCityDouble = Double.parseDouble(latitudeOfSearchedCity);
            double longitudeOfSearchedCityDouble = Double.parseDouble(longitudeOfSearchedCity);

            double distanceBetweenTheCityAndEarthquakes = 
                    harvesine.haversine(latitudeOfSearchedCityDouble, longitudeOfSearchedCityDouble, latitude, longitude);

            distanceAndPlaceMapForAllCities.put(distanceBetweenTheCityAndEarthquakes, place);


        } catch (ClassCastException | NullPointerException e) {
            continue;
        }
    }           
}

public TreeMap<Double, String> read10closestCities() {
    TreeMap<Double, String> first10resultsFromTheList = distanceAndPlaceMapForAllCities.entrySet().stream()
            .limit(10)
            .collect(TreeMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), Map::putAll);  
    return first10resultsFromTheList;
}
}

HarvesineFormula.java

public class HarvesineFormula {

public double haversine(double latitude1stCity, double longitude1stCity, 
        double latitude2ndCity, double longitude2ndCity) {

    double distanceBetweenLatitudes = Math.toRadians(latitude2ndCity - latitude1stCity);
    double distanceBetweenLongitudes = Math.toRadians(longitude2ndCity - longitude1stCity);
    latitude1stCity = Math.toRadians(latitude1stCity);
    latitude2ndCity = Math.toRadians(latitude2ndCity);
    double a = Math.pow(Math.sin(distanceBetweenLatitudes / 2), 2) + 
            Math.pow(Math.sin(distanceBetweenLongitudes / 2), 2) * 
            Math.cos(latitude1stCity) * Math.cos(latitude2ndCity);
    double radiusOfTheEarth = 6371;
    double c = 2 * Math.asin(Math.sqrt(a));
    return radiusOfTheEarth * c;
}
}

earthquakesList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html>
<head>
<%@ page isELIgnored="false" %>
<meta charset="UTF-8">
</head>
<body>


        <div>
            <form action="/read" method="post">
                <label>Latitude</label> 
                <fieldset>
                    <input type="text" 
                    name="latitudeOfSearchedCity" 
                    id="latitudeOfSearchedCity" 
                    class="form-control" 
                    oninvalid="this.setCustomValidity('Type in latitude in a format 00.000')"
                    onchange="try{setCustomValidity('')}catch(e){}"
                    oninput="setCustomValidity(' ')"
                    pattern="^[-]?(\d+|\d*\.\d+)$"
                    required="required" />
                </fieldset>

                <label>Longitude</label> 
                <fieldset>
                    <input type="text" 
                    name="longitudeOfSearchedCity" 
                    id="longitudeOfSearchedCity" 
                    class="form-control" 
                    oninvalid="this.setCustomValidity('Type in longitude in a format 00.000')"
                    onchange="try{setCustomValidity('')}catch(e){}"
                    oninput="setCustomValidity(' ')"            
                    pattern="^[-]?(\d+|\d*\.\d+)$" 
                    required="required" />
                </fieldset>

                <fieldset>
                <label>Select a city</label> 
                <select id="countrySelect">
                    <option>None</option>
                    <option value="35.084385_-106.650421">Albuquerque</option>                              
                    <option value="33.748997_-84.387985">Atlanta</option>
                    <option value="41.878113_-87.629799">Chicago</option>                           
                    <option value="32.776665_-96.796989">Dallas</option>
                    <option value="39.739235_-104.990250">Denver</option>   
                    <option value="31.761877_-106.485023">El Paso</option>                                                          
                    <option value="29.760427_-95.369804">Houston</option>                                                       
                    <option value="30.332184_-81.655647">Jacksonville</option>
                    <option value="39.099728_-94.578568">Kansas City</option>   
                    <option value="36.169941_-115.139832">Las Vegas</option>                                
                    <option value="34.052235_-118.243683">Los Angeles</option>                                                      
                    <option value="35.149532_-90.048981">Memphis</option>   
                    <option value="43.038902_-87.906471">Milwaukee</option>         
                    <option value="44.977753_-93.265015">Minneapolis</option>                                                       
                    <option value="29.951065_-90.071533">New Orleans</option>                                                                                   
                    <option value="40.712776_-74.005974">New York City</option>
                    <option value="28.538336_-81.379234">Orlando</option>                       
                    <option value="39.952583_-75.165222">Philadelphia</option>
                    <option value="33.448376_-112.074036">Phoenix</option>                              
                    <option value="40.440624_-79.995888">Pittsburgh</option>
                    <option value="45.512230_-122.658722">Portland</option>                                 
                    <option value="38.581573_-121.494400">Sacramento</option>                                   
                    <option value="29.424122_-98.493629">San Antonio</option>   
                    <option value="32.715736_-117.161087">San Diego</option>                                        
                    <option value="37.338207_-121.886330">San Jose</option>                                                                                                 
                    <option value="47.606209_-122.33206">Seattle</option>
                    <option value="38.627003_-90.199402">St. Louis</option> 
                    <option value="32.222607_-110.974709">Tucson</option>                           
                    <option value="38.907192_-77.036873">Washington D.C.</option>                                                                                           
                </select>
                </fieldset>

                <br />

                <button type="submit">Submit</button>
            </form>
        </div>

        <div class="resultsTable2">
            <table>
                <thead>
                    <tr>
                        <th>Distance</th>
                        <th>Location</th>

                    </tr>
                </thead>

                <tbody>
                    <c:forEach items="${outputMap}" var="entry">
                        <tr>
                            <td><fmt:formatNumber type="number" maxFractionDigits="1"
                                    value="${entry.key}" /> KM</td>
                            <td><c:out value="${entry.value}" /></td>
                        </tr>
                    </c:forEach>
                </tbody>
            </table>
        </div>


<script src="webjars/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script>
$('#countrySelect').on('change', function () {
    var val = this.value;
    var parts = val.split("_");
    $('#latitudeOfSearchedCity').val(parts[0]);
    $('#longitudeOfSearchedCity').val(parts[1]);
});
</script>

</body>
</html>

web.xml

    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

    <display-name>Archetype Created Web Application</display-name>
      <servlet>
      <servlet-name>PrintEarthquakesServlet</servlet-name>
      <servlet-class>com.dominikazb.earthquakes.servlets.PrintEarthquakesServlet</servlet-class>
      </servlet>
      <servlet>
      <servlet-name>ReadLongitudeAndLatitudeServlet</servlet-name>
        <servlet-class>com.dominikazb.earthquakes.servlets.ReadLongitudeAndLatitudeServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>PrintEarthquakesServlet</servlet-name>
        <url-pattern>/PrintEarthquakesServlet</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>ReadLongitudeAndLatitudeServlet</servlet-name>
        <url-pattern>/ReadLongitudeAndLatitudeServlet</url-pattern>
      </servlet-mapping>

      <welcome-file-list>
        <welcome-file>earthquakesList.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dominikazb</groupId>
<artifactId>10closestEarthquakes</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>10closestEarthquakes Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
    <tomcat.version>7.0.50</tomcat.version>
</properties>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.github.jsimone/webapp-runner -->
    <dependency>
        <groupId>com.github.jsimone</groupId>
        <artifactId>webapp-runner</artifactId>
        <version>9.0.27.1</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>bootstrap</artifactId>
        <version>3.3.6</version>
    </dependency>

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>jquery</artifactId>
        <version>1.9.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.10</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
</dependencies>

<build>
    <finalName>10closestEarthquakes</finalName>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <wtpversion>2.0</wtpversion>
                <wtpContextName>todo</wtpContextName>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <verbose>true</verbose>
                <source>1.8</source>
                <target>1.8</target>
                <showWarnings>true</showWarnings>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <path>/</path>
                <contextReloadable>true</contextReloadable>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <webappDirectory>${project.build.directory}/${project.artifactId}
                </webappDirectory>
                <warName>${project.artifactId}</warName>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>com.github.jsimone</groupId>
                                <artifactId>webapp-runner</artifactId>
                                <version>9.0.27.0</version>
                                <destFileName>webapp-runner.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>

</build>
</project>

完整代码可用here。请帮忙??

java json servlets
2个回答
0
投票

我看过您的代码,并在ReadJsonFile.java中发现了一些奇怪的东西

public static ReadJsonFile getReadJson() {
  return readJson;
}

从上面的代码看来,您想将您的类用作Singleton但是,然后将一些值保存在静态字段中

longitude = (double) coordinatesArrayList.get(0);
latitude = (double) coordinatesArrayList.get(1);

我的提示是尝试消除静态字段。在我看来,您不需要它们。


0
投票

对于第一个问题,ReadJson类及其使用方式存在一些问题。

  1. [ReadJson用作Singleton,即,只有一个此类的实例,并且它将在所有HTTP请求之间共享。
  2. 每个新的HTTP请求将填充ReadJson类的distanceAndPlaceMapForAllCities成员。请注意,此成员将包含所有先前请求的数据。它也是按距离排序的TreeMap,因此一段时间后得到相同的结果并不奇怪。
  3. 每个HTTP请求都将通过网络获取json数据文件并进行解析。

您应该重构JSON数据的处理。仅读取一次JSON文件(或每天一次以获取更新)。计算distanceAndPlaceMapForAllCities时,请确保对每个请求使用一个新实例。

© www.soinside.com 2019 - 2024. All rights reserved.