文字列がnull
値を部分文字列化しようとしているため、このエラーが発生していると推測しています。しかし、".length() > 0"
部分はその問題を排除しないでしょうか?
Javaスニペット:
if (itemdescription.length() > 0) {
pstmt2.setString(3, itemdescription.substring(0,38));
}
else {
pstmt2.setString(3, "_");
}
私はこのエラーを受け取りました:
Java.lang.StringIndexOutOfBoundsException: String index out of range: 38
at Java.lang.String.substring(Unknown Source)
at MASInsert2.itemimport(MASInsert2.Java:192)
at MASInsert2.processRequest(MASInsert2.Java:125)
at MASInsert2.doGet(MASInsert2.Java:219)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:627)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:729)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:269)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:188)
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:213)
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:172)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:127)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:117)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:108)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:174)
at org.Apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.Java:835)
at org.Apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.Java:640)
at org.Apache.Tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.Java:1286)
at Java.lang.Thread.run(Unknown Source)
文字列がNull値を部分文字列化しようとしているため、このエラーが発生していると推測しています。
いいえ、itemdescriptionがnullのときにitemdescription.length()を呼び出してもStringIndexOutOfBoundsExceptionは生成されませんが、本質的にnullでメソッドを呼び出そうとするため、NullPointerExceptionが生成されます。
他の人が示したように、StringIndexOutOfBoundsExceptionはitemdescriptionが少なくとも38文字の長さではないことを示します。おそらく両方の条件を処理する必要があります(切り捨てたいと仮定しています):
final String value;
if (itemdescription == null || itemdescription.length() <= 0) {
value = "_";
} else if (itemdescription.length() <= 38) {
value = itemdescription;
} else {
value = itemdescription.substring(0, 38);
}
pstmt2.setString(3, value);
あなたがそれをたくさんやるなら、ユーティリティ機能のための良い場所かもしれません...
substring
が他の言語のように短い文字列を処理する方法で実装されていないのは残念です。 Python。
OK、それを変更することはできず、if-else句の代わりにsubstr
を使用するたびにこのEdgeのケースを考慮する必要があります。
myText.substring(0, Math.min(6, myText.length()))
文字列の長さが38以上かどうかを確認する必要があります。
Apache commons lang をお勧めします。ワンライナーが問題を処理します。
pstmt2.setString(3, StringUtils.defaultIfEmpty(
StringUtils.subString(itemdescription,0, 38), "_"));
substring(0,38)
は、文字列が38文字以上でなければならないことを意味します。そうでない場合、「文字列インデックスは範囲外です」。
if (itemdescription != null && itemdescription.length() > 0) {
pstmt2.setString(3, itemdescription.substring(0, Math.min(itemdescription.length(), 38)));
} else {
pstmt2.setString(3, "_");
}
列の長さは38文字であると想定しているため、データベースに収まるようにtruncateitemdescription
にする必要があります。次のようなユーティリティ関数は、必要な処理を行う必要があります。
/**
* Truncates s to fit within len. If s is null, null is returned.
**/
public String truncate(String s, int len) {
if (s == null) return null;
return s.substring(0, Math.min(len, s.length()));
}
その後、次のように呼び出すだけです:
String value = "_";
if (itemdescription != null && itemdescription.length() > 0) {
value = truncate(itemdescription, 38);
}
pstmt2.setString(3, value);
Javaのsubstring
メソッドは、文字列より長いインデックスで始まる部分文字列を取得しようとすると失敗します。
簡単な代替手段は Apache Commons StringUtils.substring
:
public static String substring(String str, int start)
Gets a substring from the specified String avoiding exceptions.
A negative start position can be used to start n characters from the end of the String.
A null String will return null. An empty ("") String will return "".
StringUtils.substring(null, *) = null
StringUtils.substring("", *) = ""
StringUtils.substring("abc", 0) = "abc"
StringUtils.substring("abc", 2) = "c"
StringUtils.substring("abc", 4) = ""
StringUtils.substring("abc", -2) = "bc"
StringUtils.substring("abc", -4) = "abc"
Parameters:
str - the String to get the substring from, may be null
start - the position to start from, negative means count back from the end of the String by this many characters
Returns:
substring from start position, null if null String input
何らかの理由でApache Commons libを使用できない場合は、 ソースから必要な部分を取得する
// Substring
//-----------------------------------------------------------------------
/**
* <p>Gets a substring from the specified String avoiding exceptions.</p>
*
* <p>A negative start position can be used to start {@code n}
* characters from the end of the String.</p>
*
* <p>A {@code null} String will return {@code null}.
* An empty ("") String will return "".</p>
*
* <pre>
* StringUtils.substring(null, *) = null
* StringUtils.substring("", *) = ""
* StringUtils.substring("abc", 0) = "abc"
* StringUtils.substring("abc", 2) = "c"
* StringUtils.substring("abc", 4) = ""
* StringUtils.substring("abc", -2) = "bc"
* StringUtils.substring("abc", -4) = "abc"
* </pre>
*
* @param str the String to get the substring from, may be null
* @param start the position to start from, negative means
* count back from the end of the String by this many characters
* @return substring from start position, {@code null} if null String input
*/
public static String substring(final String str, int start) {
if (str == null) {
return null;
}
// handle negatives, which means last n characters
if (start < 0) {
start = str.length() + start; // remember start is negative
}
if (start < 0) {
start = 0;
}
if (start > str.length()) {
return EMPTY;
}
return str.substring(start);
}
itemdescription
は38文字より短いです。 StringOutOfBoundsException
がスローされている理由です。
.length() > 0
をチェックすると、単にString
にnull以外の値があることを確認します。必要なのは、長さが十分に長いことを確認することです。あなたが試すことができます:
if(itemdescription.length() > 38)
...
これが適切な場合、substringの代わりにmatchesを使用します。
substringの場合:
if( myString.substring(1,17).equals("Someting I expect") ) {
// Do stuff
}
// Does NOT work if myString is too short
matches(正規表現を使用する必要があります):
if( myString.matches("Someting I expect.*") ) {
// Do stuff
}
// This works with all strings
文字列の長さを確認する必要があります。 Stringがnull
でない限りsubstring(0,38)
を実行できると仮定しますが、実際には少なくとも38文字の長さのStringが必要です。