2

Java-EEでWebアプリをコーディングしていますが、ユーザー入力でエラーを表示しようとすると、非常に予期しない結果が発生します。

このアプリは、JSP/サーブレット/フォーム/Beanモデルに基づいて構築されています。基本的に、JSPはデータをリクエストに格納し、それをサーブレットに転送します。次に、サーブレットはリクエストをフォームにrawで転送し、フォームはデータを読み取り、必要なチェックを実行して、Beanをサーブレットに返します。

ほとんどのフィールドには特定の値が必要ですが、その他のフィールドは単にnull以外である必要があります。

入力を保護するためにエラー検出コードを記述しましたが、非常に奇妙な結果になりました。

  • フィールドがnull以外であるが、値が正しくない場合(たとえば、00:00〜23:59の範囲外にある時間)、HashMapに格納されているエラーメッセージとともに適切なエラーが返されます。私のJSPでアクセスできます。
  • ${!empty errors.dataErrors}ただし、フィールドがnullの場合、メッセージが返され、おそらくHashMapにも格納されます(テストがtrueを返し、エラーフィールドがJSPに表示されるため、これはわかります)が、の値にアクセスする方法はありません。エラー

コードを検索しましたが、エラーの原因がわかりません。問題がどこから来ているのか誰かが知っている場合のスニペットは次のとおりです

サーブレットからのdoPostメソッド:

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
    NewBookingForm form = new NewBookingForm();
    Booking booking = form.registerBooking(request);
    String VUE;

    request.setAttribute("booking", booking);
    request.setAttribute("errors", form);

    this.getServletContext().getRequestDispatcher(VIEW).forward(request, response);
}

マップはNewBookingFormクラスのフィールドであり、registerBookingこのようにメソッドの外部で宣言および初期化されprivate Map<String,String> dataErrors = new HashMap<String,String>();、プライベートセッター(クラス内のアクセス用)とパブリックゲッター(サーブレットおよびJSP内のアクセス用)があります。

フォームクラス内で、この関数を使用してフィールド値を取得します。

private static String getFieldValue(HttpServletRequest request, String fieldName)
{
    String value = request.getParameter(fieldName);
    if (value == null || value.trim().length() == 0){return null;}
    else{return value;}
}

メソッドの最初のように一連の呼び出しで値を取得した後、次のString fieldDepartureStation = getFieldValue(request, FIELD_DEPARTURE_STATION);ようなtry/catchブロックを使用して値を確認します。

try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}

データに特定の値の範囲が必要な場合、または単にnull以外である必要がある場合、検証クラス内の検証メソッドは少し異なります。

前者の場合、次のようになります。

public void departureTime(String time) throws Exception
{
    if (!validationRETime(time)) { throw new Exception("Please input a time with the hh:mm pattern"); }
}
....
private boolean validationRETime(String strTime)
{
    String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
    if (strTime.matches(regExp))
    {
        return true;
    }
    else
    {
        return false;
    }
}

後者の場合、それらは単に

public void departureStation(String station) throws Exception
{
    if (station.equals(null)) { throw new Exception("Please input a departure station"); }
}

最後に、私のJSPでは、次のコードを使用してエラーを表示します。

<c:if test="${!empty errors.dataErrors}">
     <p>Errors</p>
     <c:forEach items="${errors.dataErrors}" var="message">
           <p><c:out value="${message.value}" /></p>
     </c:forEach>
</c:if>

また、意図的に間違った値を入力した場合はエラー段落が表示され<c:forEach>ますが、間違ったフィールドがnullではないが値が正しくない場合にのみ、エラーメッセージがループして表示されます。したがって、null以外である必要があるだけのフィールドでは、メッセージは表示されません(ただし、エラーは表示されます)

これらは私が考えることができるすべてのことであり、おそらくうまくいかない可能性がありますが、私はまだそれらがどこで行われたかを発見しておらず、誰かが私を助けてくれるなら、私はとてもうれしいです。

4

2 に答える 2

2

問題はあなたのdepartureStation方法にあります: -

public void departureStation(String station) throws Exception
{
    if (station.equals(null)) { 
        throw new Exception("Please input a departure station"); 
    }
}

値のテストnull自体がNPE. station.equals(null)したがって、が に対して実行されるとすぐにstation = null例外NPEがスローされ、それが呼び出し元に伝播されます。したがって、ifブロックは実行されません。したがって、あなたがException考えているように、あなたは投げていません。

NPEここで、スローされる には が含まれていないことにも注意してくださいmessage。それで、それe.getMessage()に戻りnullます。

それでは、呼び出し元に戻りましょう: -

try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}

Exception Handlingここでは、 のキャッチ ブロックを使用して、の世界で最大の犯罪を行っていますException。はすべての例外のスーパー クラスであるためException、すべての例外を同じ方法で処理します。したがって、 を消費しNPE、 に渡しsetDataErrors()ます。

したがって、もちろんエラーが発生しますが、値e.getMessage()null. そのため、メッセージが表示されません。上記ののlogging値でテストすることもできます。e.getMessage()catch block


解決 ??

nullこれでチェックを変更するだけです:-

if (station == null) { 
    throw new Exception("Please input a departure station"); 
}

そして、すべてがうまくいくでしょう。すべてのメソッドでこの変更を行う必要があると思います。常にnull checkusing==演算子を実行します。

于 2013-01-31T12:35:23.890 に答える
1
public class Test {

    public static void main(String[] args) {
        Test  c = new Test ();
        try {
            c.departureTime("30:30");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        try {
            c.departureTime(null);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public void departureTime(String time) throws Exception {
        if (!validationRETime(time)) {
            throw new Exception("Please input a time with the hh:mm pattern");
        }
    }

    private boolean validationRETime(String strTime) {
        String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
        if (strTime.matches(regExp)) {
            return true;
        } else {
            return false;
        }
    }
}

上記のコードを実行することで、問題を解決できます。簡単に言えば、 exp.getMessage() が常に値を持つようにする必要があります。この問題を解決するには、departmentTime() メソッドを微調整して、よりきめ細かい例外処理を提供することをお勧めします。

于 2013-01-31T11:28:30.427 に答える