0

所以我试图从文件读取器中填充两个数组。我相信这需要嵌套循环。我认为我走的是正确的道路,但自昨天以来我一直陷入困境。此程序的目的是通过jsp启动程序并动态读取值。任何帮助真的会被赞赏。我想我正走在正确的轨道上,但我似乎无法完成自己的事业。 fxRates.csv的第一行应该填充到currencyCodes数组中,其余行应该填充到2d数组fxExchangeRates中。我得到的代码没有任何错误,但现在我得到的是这样的,当我尝试运行程序:enter image description here分割为字符串数组时空指针异常

以下是错误日志:

Info: visiting unvisited references 
Info: visiting unvisited references 
Info: visiting unvisited references 
Warning: Ignore WEB-INF/sun-web.xml in archive /G:/School/Java II/Labs/MidtermAD/build/web/, as WLS counterpart runtime xml WEB-INF/glassfish-web.xml is present in the same archive. 
Info: Loading application [MidtermAD] at [/MidtermAD] 
Info: MidtermAD was successfully deployed in 464 milliseconds. 
Warning: StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception 
java.lang.NullPointerException 
    at java.lang.String.split(String.java:2337) 
    at java.lang.String.split(String.java:2422) 
    at data.FxDataModel.<init>(FxDataModel.java:38) 
    at org.apache.jsp.fxCalc_jsp.jspInit(fxCalc_jsp.java:45) 
    at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:92) 
    at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:210) 
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388) 
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473) 
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) 
    at java.lang.Thread.run(Thread.java:745) 

fxInit.jsp:

<%@page import="java.io.*"%> 
<%@page import="java.util.*"%> 
<%@ page import="data.FxDataModel"%> 
<%! 

private FxDataModel fxDataModel; 


     public void jspInit(){ 
     Properties fxProps = new Properties(); 


     ServletContext context = getServletContext(); 
     fxProps.getProperty(FxDataModel.FX_PRP_FILE_NAME_KEY); 

     context.getRealPath(context.getInitParameter(FxDataModel.FX_PRP_FILE_NAME_KEY)); 

     try{ 
      FileInputStream input = new FileInputStream(FxDataModel.FX_PRP_FILE_NAME_KEY); 
      fxProps.load(input); 
      input.close(); 
     }catch(IOException e){ 

      FileInputStream input = null; 
     } 
     context.getRealPath(fxProps.getProperty(FxDataModel.FX_RATE_FILE_NAME_KEY)); 
     try{ 
      FileInputStream input = new FileInputStream(FxDataModel.FX_RATE_FILE_NAME_KEY); 
      fxProps.load(input); 
      input.close(); 
     }catch(IOException e){ 

      FileInputStream input = null; 
     } 

     fxDataModel = new FxDataModel(fxProps); 


     } 
%> 

FxDataModel.Java:

package data; 

import java.util.*; 


public class FxDataModel { 

    public static final String FX_PRP_FILE_NAME_KEY = "fx.prp.file.name"; 
    public static final String FX_RATE_FILE_NAME_KEY = "fx.rates.file.name"; 
    public static final String FX_RATES_FILE_DLMTR_KEY = "fx.rates.file.dlmtr"; 
    public static final String SRC_AMT_KEY = "src.amt"; 
    public static final String SRC_CUCY_KEY = "src.cucy"; 
    public static final String DST_AMT_KEY = "dst.amt"; 
    public static final String DST_CUCY_KEY = "dst.cucy"; 

    private Properties fxProps = new Properties(); 

    private double [][] fxExchangeRates; 
    private String[] fxCurrencies; 

    public FxDataModel(Properties fxProps)  
     { 
      this.fxProps = fxProps; 
      String[] rateStrings; 
      String record; 
      fxProps .setProperty(FX_RATES_FILE_DLMTR_KEY,"fx.rates.file.dlmtr"); 
      String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY); 
      Scanner reader = new Scanner(FX_RATE_FILE_NAME_KEY); 


        fxCurrencies = reader.nextLine().split(delimiter); 

     for(int i = 0 ; i < fxCurrencies.length ; i++){ 

      record= reader.nextLine(); 
      rateStrings = record.split(delimiter); 
      fxExchangeRates[i] = new double[fxCurrencies.length]; 

      for(int j = 0 ; j < rateStrings.length ; j++){ 

      fxExchangeRates[i][j]= Double.parseDouble(rateStrings[j]); 

     } 

     reader.close(); 

     } 

     } 

     public Properties getFxProps() 

     { 


      return fxProps; 


     } 
    public String[] getFxCurrencies(){ 
     return fxCurrencies; 
    } 

    public double getFxRate(final String inNumber, final String outNumber){ 

     int Currency1; 
     int Currency2; 
     double rate; 

     for(Currency1 = 0; Currency1 <getFxCurrencies().length; Currency1++){ 

      if(inNumber.equals(fxCurrencies[Currency1])){ 
       break; 
      } 
     } 

     for(Currency2 = 0; Currency2 <getFxCurrencies().length; Currency2++){ 

      if(outNumber.equals(fxCurrencies[Currency2])){ 
       break; 
      } 
     } 


     rate = fxExchangeRates[Currency1][Currency2]; 
     return rate; 

     } 

    } 

fxCalc.jsp

<%@include file="fxInit.jsp"%> 
<%  
     Properties fxProps = fxDataModel.getFxProps(); 
     String srcAmtName = fxProps.getProperty(FxDataModel.SRC_AMT_KEY); 
     String dstAmtName = fxProps.getProperty(FxDataModel.DST_AMT_KEY); 
     String srcCucyName = fxProps.getProperty(FxDataModel.SRC_CUCY_KEY); 
     String dstCucyName = fxProps.getProperty(FxDataModel.DST_CUCY_KEY); 
     String Curr1 = request.getParameter(srcAmtName); 
     String Curr2 = request.getParameter(dstAmtName); 
     String formInput; 
     String formOutput; 

     String[] currencies = fxDataModel.getFxCurrencies(); 


     try { 

      formInput = request.getParameter(srcAmtName); 
      Double formDouble = Double.parseDouble(formInput); 
      Double Conversion = fxDataModel.getFxRate(Curr1,Curr2)*formDouble; 
      formOutput = String.valueOf(Conversion); 

     } catch (NumberFormatException ex) { 
      Curr1= Curr2 = currencies[0]; 
      formInput = (""); 
      formOutput = (""); 
     } catch (NullPointerException npe){ 

      Curr1= Curr2 = currencies[0]; 
      formInput = (""); 
      formOutput = (""); 

     } 

%> 

<html> 
    <head> 
     <title>F/X Calculator</title> 
     <meta charset="UTF-8"> 
     <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    </head> 

    <style> 

     h1{ 
      color: white; 
      font-family: verdana; 
      font-size: 200%; 
      font-style: italic; 
      text-align: center; 
     } 
     hr{ 
      color:white; 

     } 

     select{ 
      margin-top: 30px; 
      margin-right:10px; 
     } 
     input{ 

      margin-top: 30px; 
      margin-right:10px; 
     } 
    </style> 


    <body bgcolor = "blue"> 

     <h1> 
      Money Banks F/X Calculator<br> 
     </h1> 
     <hr> 
     <div align="center"> 
     <form name ="fxCalc" action="fxCalc.jsp" method="POST"> 


     <select name="<%=srcCucyName%>"> 
      <% for (String currency : currencies) { %> 
       <option value="<%=currency%>" <%=currency.equals(Curr1)?"selected":""%>><%=currency%></option> 
      <%}%> 
     </select> 


      <input name="<%=srcAmtName%>" type="text" value = <%=formInput%> > 

     <select name="<%=dstCucyName%>"> 
      <% for (String currency : currencies) { %> 
       <option value="<%=currency%>" <%=currency.equals(Curr2)?"selected":""%>><%=currency%></option> 
      <%}%> 
     </select> 


      <input name="<%=dstAmtName%>" type="text" disabled="disabled" value = <%=formOutput%>> 

      <br> 


      <input name="submitbutton" type="submit" value="Convert" name="Convert"/> 
      <input name="resetbutton" type="reset" value="Reset"/> 




     <form/> 
     <div/> 
    </body> 
</html> 

我真的不理解的一件事是我不应该在html中“硬编码”表单控件,所以这就是为什么这些“SRC_AMT_KEY”键被提供。我只是不确定如何实现它们。尽我所能,但我完全不理解这一部分。键是否应该替换“Curr1”和“Curr2”等变量?这是应用程序以前的工作方式,但我们现在正在更新它,以便没有硬编码。我非常感谢任何帮助理解这个项目。我已经坚持了几天,现在我会继续更新代码,如果我取得任何进展。谢谢!

这里也是fxCalc.prp文件的内容:

dst.amt=dstAmt 
dst.cucy=dstCucy 
fx.rates.file.dlmtr=, 
fx.rates.file.name=/WEB-INF/fxRates.csv 
src.amt=srcAmt 
src.cucy=srcCucy 

的fxRates.csv文件还包含这些代码:

CAD,EUR,GBP,USD 
1.0,0.624514066,0.588714763,0.810307 
1.601244959,1.0,0.942676548,1.2975 
1.698615463,1.060809248,1.0,1.3764 
1.234100162,0.772200772,.726532984,1.0 
+15

太多的代码。只提供相关的内容。 [MCVE](http://stackoverflow.com/help/mcve)。 – YoungHobbit

+0

好的..谢谢。我删除了一些东西并缩小了问题的范围。 – DeathWish

+1

您从未使用任何值填充'fxProps'属性。 –

回答

2

在FxDataModel.Java类 声明的属性参考为private Properties fxProps;

但您没有分配属性对象。默认情况下,它分配为null,空值为fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY);。那么在运行时JVM会抛出NullPointerException。

解决方案:

private Properties fxProps = new Properties(); 
fxProps .setProperty(FX_RATES_FILE_DLMTR_KEY,"fx.rates.file.dlmtr"); 
private String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY); 
+0

检查FxDataModel.Java 上的更新我做了你的建议,但我仍然得到一个NullPointerException。 它始终指向第38行,这是我使用分隔符分割文件的第一行时的情况。 – DeathWish

+0

如果JVM trows在java.lang.String.split(String.java:2337) 像 显示java.lang.NullPointerException 错误在java.lang.String.split(String.java:2422) If和仅当分隔符值为空时。 您的情况如下: String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY); //返回null fxCurrencies = reader.nextLine()。split(delimiter); 因此,该split(null)方法抛出NullPointerException。 –

+0

但是,分隔符如何可以为空。我将它设置为String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY);我发起了像你告诉我的fxProps。有没有其他的东西导致值为空? – DeathWish