私は私のサービスにジャクソン2でSpring 4 MVCを使用しています。操作の1つについて、主要なラクダケースWordの属性を持つリクエストオブジェクトがあります。これは長さが1文字のみです。
private String aLogId;
このクラスには、適切な名前のゲッターとセッターがあります。
public String getALogId() { return aLogId; }
public void setALogId(String aLogId) { this.aLogId = aLogId; }
ただし、対応するJSONプロパティを使用してこのサービスにリクエストを投稿しようとすると:
{"aLogId":"This is a log id"}
フィールドが認識されず、コントローラークラスが呼び出されないという、Springフレームワークからの500応答を受信しています。
JSONを読み取れませんでした:認識されないフィールド「aLogId」(クラス
ただし、「L」を小文字に変更すると、要求は期待どおりにデシリアライズされ、コントローラークラスがヒットします。
{"alogId":"This is a log id"}
明らかにジャクソンは、属性のキャメルケース規則の2番目の単語であり、大文字にすることを意図しているのに、「L」が小文字であると予期するのはなぜですか。それは、最初のWordが1文字だけの長さだからですか?
リクエストオブジェクトには、最初のWordが複数の文字である他の属性があり、属性は、大文字と小文字が一致しないこの同じ問題に直面しません。
私の理解では、JacksonはデフォルトでJava Beanの命名規則に非常に近いが厳密には同じではない独自の命名規則を使用します。MapperFeatureオプション、MapperFeature.USE_STD_BEAN_NAMING)が追加されましたJackson 2.5.0では、Java Bean命名規則を使用するようにJacksonに指示します- Jackson Issue 65 を参照してください。後方互換性のため、MapperFeature.USE_STD_BEAN_NAMINGのデフォルト値は偽。
これは私のために働いています。ゲッターの@JsonPropertyアノテーション!
import com.fasterxml.jackson.annotation.JsonProperty;
public class PaytmRequestJson {
private String ORDERID;
private String MID;
private String CHECKSUMHASH;
@JsonProperty("ORDERID")
public String getORDERID() {
return ORDERID;
}
public void setORDERID(String ORDERID) {
this.ORDERID = ORDERID;
}
@JsonProperty("MID")
public String getMID() {
return MID;
}
public void setMID(String MID) {
this.MID = MID;
}
@JsonProperty("CHECKSUMHASH")
public String getCHECKSUMHASH() {
return CHECKSUMHASH;
}
public void setCHECKSUMHASH(String CHECKSUMHASH) {
this.CHECKSUMHASH = CHECKSUMHASH;
}
}
@JsonProperty
現在の回答で示唆されているように、すべてのプロパティに対してそれを繰り返す必要があり、侵襲的であるという欠点があります(マッピングされているクラスを変更する必要があります)。
より一般的なアプローチは、カスタムプロパティ命名戦略を提供することです。
Java:
public class CustomSnakeCase extends PropertyNamingStrategy.PropertyNamingStrategyBase {
private static final Pattern REGEX = Pattern.compile("[A-Z]");
@Override
public String translate(String input) {
if (input == null)
return input; // garbage in, garbage out
if (!input.isEmpty() && Character.isUpperCase(input.charAt(0)))
input = input.substring(0, 1).toLowerCase() + input.substring(1);
return REGEX.matcher(input).replaceAll("_$0").toLowerCase();
}
}
Kotlin:
class CustomSnakeCase : PropertyNamingStrategy.PropertyNamingStrategyBase() {
private companion object {
val REGEX = Regex("[A-Z]")
}
override fun translate(input: String?) =
input?.decapitalize()?.replace(REGEX, "_$0")?.toLowerCase()
}
使用法:
new ObjectMapper()
.setPropertyNamingStrategy(new CustomSnakeCase())
.enable(MapperFeature.USE_STD_BEAN_NAMING)
注:上記の実装では、入力がcamelCase
(大文字ではない)であると想定しています。 USE_STD_BEAN_NAMING
は、aField
などの1文字のプレフィックスを一貫して処理するために必要です。
実装は次のマッピングを提供します。必要に応じて調整できます。
camelCase snake_case
----------------------------
simple simple
a a
sepaRated sepa_rated
iOException i_o_exception
xOffset x_offset
theWWW the_w_w_w
sepaRated32 sepa_rated32
sepa32Rated sepa32_rated