web-dev-qa-db-ja.com

ジャクソンは、すべての文字列プロパティから先頭/末尾の空白を削除するように構成できますか?

JSONの例(文字列の末尾にスペースがあることに注意してください):

{ "aNumber": 0, "aString": "string   " }

理想的には、デシリアライズされたインスタンスには、aStringプロパティがあり、値が "string"(つまり、末尾のスペースなし)。これはおそらくサポートされているように見えますが、見つかりません(例:DeserializationConfig.Feature)。

Spring MVC 3.xを使用しているため、Springベースのソリューションでも問題ありません。

フォーラムポスト の提案に基づいてSpringのWebDataBinderを構成しようとしましたが、Jacksonメッセージコンバーターを使用すると機能しないようです。

@InitBinder
public void initBinder( WebDataBinder binder )
{
    binder.registerCustomEditor( String.class, new StringTrimmerEditor( " \t\r\n\f", true ) );
}
39
penfold

カスタムデシリアライザー を使用すると、次のことができます。

 <your bean>
 @JsonDeserialize(using=WhiteSpaceRemovalSerializer.class)
 public void setAString(String aString) {
    // body
 }

 <somewhere>
 public class WhiteSpaceRemovalDeserializer extends JsonDeserializer<String> {
     @Override
     public String deserialize(JsonParser jp, DeserializationContext ctxt) {
         // This is where you can deserialize your value the way you want.
         // Don't know if the following expression is correct, this is just an idea.
         return jp.getCurrentToken().asText().trim();
     }
 }

このソリューションは、このBean属性が常にこの方法でシリアル化されることを意味し、この方法で逆シリアル化するすべての属性に注釈を付ける必要があります。

18
DCKing

Spring Bootユーザー向けの簡単なソリューションは、そのwalvのSimpleModule拡張機能をアプリケーションコンテキストに追加するだけです。

package com.example;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.stereotype.Component;

import Java.io.IOException;

@Component
public class StringTrimModule extends SimpleModule {

    public StringTrimModule() {
        addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException,
                    JsonProcessingException {
                return jsonParser.getValueAsString().trim();
            }
        });
    }
}

Jacksonをカスタマイズするもう1つの方法は、com.fasterxml.jackson.databind.ModuleタイプのBeanをコンテキストに追加することです。これらはObjectMapperタイプのすべてのBeanに登録され、アプリケーションに新しい機能を追加するときにカスタムモジュールを提供するためのグローバルメカニズムを提供します。

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper

spring Bootを使用している場合ではない場合は、StringTrimModuleを自分で登録する必要があります(@Componentで注釈する必要はありません)

<bean class="org.springframework.http.converter.json.Jackson2Objec‌​tMapperFactoryBean">
    <property name="modulesToInstall" value="com.example.StringTrimModule"/>
</bean
22
Maciej Marczuk

アノテーション@JsonDeserializeの問題は、セッターに置くことを常に覚えておかなければならないことです。 Spring MVCでグローバルに「1回限り」を実現するために、次のステップを実行しました。

pom.xml:

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.3.3</version>
</dependency>

カスタムObjectMapperを作成します。

package com.mycompany;

    import Java.io.IOException;
    import org.Apache.commons.lang3.StringUtils;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
    import com.fasterxml.jackson.databind.module.SimpleModule;

    public class MyObjectMapper extends ObjectMapper {

        public MyObjectMapper() {
            registerModule(new MyModule());
        }
    }

    class MyModule extends SimpleModule {

        public MyModule() {
            addDeserializer(String.class, new StdScalarDeserializer<String>  (String.class) {
                @Override
                public String deserialize(JsonParser jp, DeserializationContext  ctxt) throws IOException,
                    JsonProcessingException {
                    return StringUtils.trim(jp.getValueAsString());
                }
            });
        }
    }

Springのservlet-context.xmlを更新します。

<bean id="objectMapper" class="com.mycompany.MyObjectMapper" />

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="objectMapper" />
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
15
walv

Spring Bootの場合、カスタムのデシリアライザを マニュアルに記載されている として作成する必要があります。

以下は私のGroovyコードですが、Javaで動作するように自由に変更してください。

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import org.springframework.boot.jackson.JsonComponent

import static com.fasterxml.jackson.core.JsonToken.VALUE_STRING

@JsonComponent
class TrimmingJsonDeserializer extends JsonDeserializer<String> {

    @Override
    String deserialize(JsonParser parser, DeserializationContext context) {
        parser.hasToken(VALUE_STRING) ? parser.text?.trim() : null
    }
}
5
adarshr

com.fasterxml.jackson.dataformat

pom.xml

   <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-csv</artifactId>
      <version>2.5.3</version>
    </dependency>

CsvUtil.Java

     CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader().sortedBy();
     CsvMapper mapper = new CsvMapper();
     mapper.enable(CsvParser.Feature.TRIM_SPACES);
     InputStream inputStream = ResourceUtils.getURL(fileName).openStream();
     MappingIterator<T> readValues =
          mapper.readerFor(type).with(bootstrapSchema).readValues(inputStream);
4
vanduc1102

デフォルトのStringDeserializerは、サードパーティのライブラリで使用できる特定のケース( here および here を参照)をすでに処理しているため、拡張する方が良いと思います。以下はSpring Bootの設定です。

@JsonComponent
public class StringDeserializer extends com.fasterxml.jackson.databind.deser.std.StringDeserializer {

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = super.deserialize(p, ctxt);
        return value != null ? value.trim() : null;
    }
}
0
Eugene Maysyuk