Java WebApp 不断返回相同的结果

标签 java json servlets

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

问题 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. 我从下拉列表中选择了另一个城市,输入字段正在填充新坐标,然后我按提交,但我不断收到警告,数字格式不正确(就像程序甚至尽管输入是新的,但仍会读取 39.099728sdjfhjsdf)。

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

读取LongitudeAndLatitudeServlet.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 。请帮忙??

最佳答案

主要逻辑错误在这里:

distanceAndPlaceMapForAllCities.put(distanceBetweenTheCityAndEarthquakes, place);

因为那张 map 会永远增长。

将此行添加到您的方法中

distanceAndPlaceMapForAllCities = new TreeMap<>();
ObjectMapper om = new ObjectMapper();           
...

您会得到正确的答案,因为每次调用该方法时您都会“重置” map 。

无论如何,我在您的代码中看到了一些其他“错误的想法”,例如

  • 使用静态字段似乎不是很有用
  • 在两个不同的函数调用之间共享“位置”(在多线程环境中,您可能会遇到问题)

无论如何,我希望能帮到你。

关于Java WebApp 不断返回相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59562194/

相关文章:

java - Spring Cloud Gateway 用于复合 API 调用?

json.Unmarshal 接口(interface)指针与稍后的类型断言

javascript - 如何在javascript和servlet之间发送和接收json数据?

mysql - 在jsp页面中不断从数据库加载数据

java - 当从 Python 调用 jar 时,如何最小化 JavaVM 的加载时间?

java - 哪个更快,equalsIgnoreCase 或 compareToIgnoreCase

java - 如何在单独的线程中运行任务特定的时间并返回结果?

javascript - Knockout.js 将 observable 与单个 json 对象绑定(bind)

java - 从未使用过 Onpostexecute 方法

javascript - 如何将表单提交的时间发送给servlet?