2017-06-06 1 views
0

タイプapplication/jsonのリクエストの場合のように、タイプapplication/x-www-form-urlencodedのリクエスト内のいくつかのパラメータのカスタムデシリアライザを書きたいとします。 @JsonDeserialize(using = AbcDeserializer.class)注釈。ジャクソンはここで使われていないとわかったが、私は春のブーツとジャクソンを使っている。Springブートでcontent-type application/x-www-form-urlencodedを使用するリクエスト用のカスタムデシリアライザ

デフォルトでオブジェクトのデシリアライズ方法を考え出しました。しかし、方法を見つけることができませんでした。

デフォルトで、スプリングがタイプapplication/x-www-form-urlencodedの要求をデシリアライズする方法はありますか?

特別な処理が必要なパラメータの注釈を使用して、この直列化を無効にすることはできますか?

答えて

1

私の解決策は、カスタムConditionalGenericConverterに基づいています。それは@ModelAttributeで動作します。実装全体を見てみましょう。

アプリケーションのブートストラップの例。

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.format.FormatterRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 

@SpringBootApplication 
public class DemoApplication { 

    @Configuration 
    public class WebConfig extends WebMvcConfigurerAdapter { 

     @Override 
     public void addFormatters(FormatterRegistry registry) { 
      registry.addConverter(new Base64JsonToObjectConverter()); 
     } 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 
} 

ここにカスタムアノテーションがあります。

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Base64Encoded { 
} 

次に、コンバータの実装が必要です。ご覧のように、コンバータはString - >Objectのみを変換します。ここで、ObjectフィールドにはBase64Encoded注釈を付ける必要があります。ここ

import com.fasterxml.jackson.databind.ObjectMapper; 
import org.springframework.core.convert.ConversionFailedException; 
import org.springframework.core.convert.TypeDescriptor; 
import org.springframework.core.convert.converter.ConditionalGenericConverter; 
import org.springframework.stereotype.Component; 

import java.io.IOException; 
import java.util.Base64; 
import java.util.Collections; 
import java.util.Set; 

@Component 
public class Base64JsonToObjectConverter implements ConditionalGenericConverter { 

    private final ObjectMapper objectMapper; 
    private final Base64.Decoder decoder; 

    public Base64JsonToObjectConverter() { 
     this.objectMapper = new ObjectMapper(); 
     this.decoder = Base64.getDecoder(); 
    } 

    @Override 
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { 
     return targetType.hasAnnotation(Base64Encoded.class); 
    } 

    @Override 
    public Set<ConvertiblePair> getConvertibleTypes() { 
     return Collections.singleton(new ConvertiblePair(String.class, Object.class)); 
    } 

    @Override 
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 
     if (source == null) { 
      return null; 
     } 
     String string = (String) source; 

     try { 
      byte[] decodedValue = this.decoder.decode(string); 

      return this.objectMapper.readValue(decodedValue, targetType.getType()); 
     } catch (IllegalArgumentException | IOException e) { 
      throw new ConversionFailedException(sourceType, targetType, source, e); 
     } 
    } 
} 

POJOの例(注釈付きフィールドを参照)、RESTコントローラです。

import com.example.demo.Base64Encoded; 

public class MyRequest { 

    private String varA; 

    @Base64Encoded 
    private B varB; 

    public String getVarA() { 
     return varA; 
    } 

    public void setVarA(String varA) { 
     this.varA = varA; 
    } 

    public B getVarB() { 
     return varB; 
    } 

    public void setVarB(B varB) { 
     this.varB = varB; 
    } 
} 
import com.example.demo.domain.MyRequest; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class DemoController { 

    @RequestMapping(path = "/test", method = RequestMethod.POST) 
    public MyRequest test(@ModelAttribute MyRequest myRequest) { 
     return myRequest; 
    } 
} 
関連する問題