Проблема сериализации в Джексоне с CommonsMultipartFile - PullRequest
4 голосов
/ 22 июля 2011

У меня есть компонент с полем типа CommonsMultipartFile, например:

public class Placement implements Serializable {

private static final long serialVersionUID = 1L;

private long placementId;
private String type;
private String placement;
private transient CommonsMultipartFile fileData;

Я отметил поле CommonsMultipartFile как временное и пытаюсь сериализовать в json, используя библиотеку Джексона. Но получаю следующую ошибку:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: nextag.travel.dashboard.model.Placement["fileData"]->org.springframework.web.multipart.commons.CommonsMultipartFile["inputStream"])

Любая помощь / предложения будут высоко оценены.

Ответы [ 2 ]

5 голосов
/ 23 июля 2011

Непонятно, как используется Джексон, поскольку в исходном вопросе не было предоставлено ни кода, ни описания.

По умолчанию Джексон пропускает все переходные поля во время сериализации.

import java.io.Serializable;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    System.out.println(mapper.writeValueAsString(new Placement()));
    // output:  {"placementId":42,"type":"OK","placement":"left"}
    // transient fields are skipped by default
  }
}

class Placement implements Serializable
{
  private static final long serialVersionUID = 1L;

  private long placementId = 42;
  private String type = "OK";
  private String placement = "left";
  private transient CommonsMultipartFile fileData = new CommonsMultipartFile();
}

class CommonsMultipartFile
{
  private String name = "Fred";
}

Однако если для переходного поля есть метод получения, то по умолчанию Джексон включает его во время сериализации.

import java.io.Serializable;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    System.out.println(mapper.writeValueAsString(new Placement()));
    // output: {"placementId":42,"type":"OK","placement":"left","fileData":{"name":"Fred"}}
    // transient fields with getters are not skipped by default
  }
}

class Placement implements Serializable
{
  private static final long serialVersionUID = 1L;

  private long placementId = 42;
  private String type = "OK";
  private String placement = "left";
  private transient CommonsMultipartFile fileData = new CommonsMultipartFile();

  public CommonsMultipartFile getFileData() {return fileData;}
}

class CommonsMultipartFile
{
  private String name = "Fred";
}

Один из вариантов конфигурации, позволяющий пропустить метод получения, - просто применить аннотацию @JsonIgnore.

import java.io.Serializable;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    System.out.println(mapper.writeValueAsString(new Placement()));
    // output: {"placementId":42,"type":"OK","placement":"left"}
    // getters marked with @JsonIgnore are ignored
  }
}

class Placement implements Serializable
{
  private static final long serialVersionUID = 1L;

  private long placementId = 42;
  private String type = "OK";
  private String placement = "left";
  private transient CommonsMultipartFile fileData = new CommonsMultipartFile();

  @JsonIgnore
  public CommonsMultipartFile getFileData() {return fileData;}
}

class CommonsMultipartFile
{
  private String name = "Fred";
}

Если невозможно или желательно отредактировать исходное определение класса для добавления аннотации @JsonIgnore, можно использовать Mix-In .

import java.io.Serializable;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    mapper.getSerializationConfig().addMixInAnnotations(Placement.class, SkipFileDataMixIn.class);
    System.out.println(mapper.writeValueAsString(new Placement()));
    // output: {"placementId":42,"type":"OK","placement":"left"}
    // getters marked with @JsonIgnore are ignored
  }
}

abstract class SkipFileDataMixIn
{
  @JsonIgnore
  public abstract CommonsMultipartFile getFileData();
}

class Placement implements Serializable
{
  private static final long serialVersionUID = 1L;

  private long placementId = 42;
  private String type = "OK";
  private String placement = "left";
  private transient CommonsMultipartFile fileData = new CommonsMultipartFile();

  public CommonsMultipartFile getFileData() {return fileData;}
}

class CommonsMultipartFile
{
  private String name = "Fred";
}

Другой подход заключается впометить тип для пропуска с @JsonIgnoreType.

import java.io.Serializable;

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonIgnoreType;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY));
    System.out.println(mapper.writeValueAsString(new Placement()));
    // output: {"placementId":42,"type":"OK","placement":"left"}
    // Types marked with @JsonIgnoreType are ignored during serialization.
  }
}

class Placement implements Serializable
{
  private static final long serialVersionUID = 1L;

  private long placementId = 42;
  private String type = "OK";
  private String placement = "left";
  private transient CommonsMultipartFile fileData = new CommonsMultipartFile();

  public CommonsMultipartFile getFileData() {return fileData;}
}

@JsonIgnoreType
class CommonsMultipartFile
{
  private String name = "Fred";
}
4 голосов
/ 23 июля 2011

Если вы не хотите сериализовать мультичасть, добавьте аннотацию @JsonIgnore в поле.

@JsonIgnore
private CommonsMultipartFile fileData;

Подробнее о аннотациях Джексона можно прочитать здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...