2016-04-11 2 views
2

Я использую Spring boot для создания спокойной службы api. Все работает правильно, за исключением того, что я не могу указать, какие данные должны быть возвращены как JSON.JsonView неправильно работает с Spring

Что я хочу, так это получить вывод без поля «content» (который в моем случае используется для хранения объекта).

Spring версия 4.2.5

Вот почему я определил 3 уровня представления (Internal быть один, используемый при получении/настройки объекта в базе данных, Public это минимальные данные для вывода на клиент):

public class EntityVisibility { 
    public static class Public { } 
    public static class Detailed extends Public { } 
    public static class Internal extends Detailed { } 
} 

Мой контроллер:

@RestController 
@RequestMapping("/api/photos") 
public class PhotoController extends BaseController { 

    @JsonView(EntityVisibility.Public.class) 
    @RequestMapping(value="/load", method= RequestMethod.GET) 
    public Response<Photo> loadFromUrl(@RequestParam("url") String urlAddress) { 

     Photo photo = ...; // create photo object 

     return new Response<>(photo); 
    } 
} 

Для меня это выглядит, что @JsonView(EntityVisibility.Public.class) сейчас работает.

класс Response (только соответствующие части):

@JsonInclude(JsonInclude.Include.NON_NULL) 
public class Response<T> { 

private T result; 

    public Response(T response) { 
     result = response; 
    } 


} 

Моя фотография класса (соответствующие части):

public class Photo extends Entity { 

    @JsonIgnore 
    protected byte[] content; 

    @JsonView(EntityVisibility.Public.class) 
    private Date modified; 

    @JsonProperty("content") 
    @JsonView(EntityVisibility.Internal.class) 
    public void setB64content(String b64content) { 
     this.content = (b64content == null) ? null : Base64.decode(b64content.getBytes()); 
    } 

    public String getB64content() { 

     try { 
      return (content.length == 0) ? null : new String(Base64.encode(content), "UTF-8"); 
     } catch (UnsupportedEncodingException e) { 
      return null; 
     } 
    } 

    public byte[] getContent() { 
     return content; 
    } 

    public void setContent(byte[] content) { 
     this.content = content; 
    } 

} 

Entity класса (соответствующие части):

@JsonInclude(JsonInclude.Include.NON_NULL) 
public class Entity { 

} 

Я Получено:

{"success":true,"result":{"mime_type":"image/png","content":"SOME_CONTENT_HERE"}}

Ожидаемый результат:

{"success":true,"result":{"mime_type":"image/png"}}

Любая помощь очень ценится!

== EDIT ==

Я создал новую очень простую установку, но это все еще не работает для меня:

Метода в @RestController:

@JsonView(EntityVisibility.Public.class) 
@RequestMapping(value="/test", method= RequestMethod.GET) 
public Response<TestObject> testMethos() { 

    TestObject testObject = new TestObject(); 
    testObject.setTest1("test1"); 
    testObject.setTest2("test2"); 
    testObject.setTest3("test3"); 

    return new Response<>(testObject); 
} 

Тест класс :

public class TestObject { 

    @JsonView(EntityVisibility.Public.class) 
    private String test1; 

    @JsonView(EntityVisibility.Detailed.class) 
    private String test2; 

    @JsonView(EntityVisibility.Internal.class) 
    private String test3; 

    @JsonIgnore 
    private String test4; 


    public String getTest1() { 
     return test1; 
    } 

    public void setTest1(String test1) { 
     this.test1 = test1; 
    } 

    public String getTest2() { 
     return test2; 
    } 

    public void setTest2(String test2) { 
     this.test2 = test2; 
    } 

    public String getTest3() { 
     return test3; 
    } 

    public void setTest3(String test3) { 
     this.test3 = test3; 
    } 

    public String getTest4() { 
     return test4; 
    } 

    public void setTest4(String test4) { 
     this.test4 = test4; 
    } 
} 

Мой pom.xml (полное):

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>ch.sumli</groupId> 
    <artifactId>SumliCore</artifactId> 
    <version>0.1</version> 
    <packaging>war</packaging> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.3.3.RELEASE</version> 
    </parent> 

    <dependencies> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-tomcat</artifactId> 
      <scope>provided</scope> 
     </dependency> 

     <dependency> 
      <groupId>com.couchbase.client</groupId> 
      <artifactId>java-client</artifactId> 
      <version>2.2.6</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-tx</artifactId> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-core</artifactId> 
      <version>4.0.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-config</artifactId> 
      <version>4.0.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-web</artifactId> 
      <version>4.0.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
      <version>4.2.5.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-validator</artifactId> 
      <version>5.2.2.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>jmimemagic</groupId> 
      <artifactId>jmimemagic</artifactId> 
      <version>0.1.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.imgscalr</groupId> 
      <artifactId>imgscalr-lib</artifactId> 
      <version>4.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.quartz-scheduler</groupId> 
      <artifactId>quartz</artifactId> 
      <version>2.2.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.quartz-scheduler</groupId> 
      <artifactId>quartz-jobs</artifactId> 
      <version>2.2.2</version> 
     </dependency> 

    </dependencies> 

    <properties> 
     <start-class>ch.sumli.Application</start-class> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
     <java.version>1.7</java.version> 
    </properties> 

    <repositories> 
     <repository> 
      <id>couchbase</id> 
      <name>couchbase repo</name> 
      <url>http://files.couchbase.com/maven2</url> 
      <snapshots><enabled>false</enabled></snapshots> 
     </repository> 
    </repositories> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

И я все еще получаю все (за исключением @JsonIgnore):

{"success":true,"result":{"test1":"test1","test2":"test2","test3":"test3"}} 
+0

Вы можете попробовать удалить @JsonInclude (JsonInclude.Include.NON_NULL) на ответ и проверить один раз? – Pavan

+0

@Pavan Я попробовал, но он не менял вывод контента. Это скорее добавило много нулевых значений: {"success": true, "error": null, "errorCode": null, "message": null, "result": {"key": "c24226c6-bfaa-4dd7 -8972-3249717e08a8 "," mime_type ":" image/png "," content ":" ... "}} – kkazakov

+0

Вы пробовали @JsonIgnore? – saml

ответ

4

После комментария раздел обсуждения с @kkazakov кажется, что проблема заключается в @JsonView из другой версии библиотеки Джексон:

Оказывается, библиотека Couchbase также имеет Джексона внутри. И пакет имя совершенно другое.Итак, я использовал @JsonView из пакета couchbase , а Jackson из Spring.

Старый пост:

Я проверил ваш код и я думаю, что он работает как задумано для меня. По крайней мере, я не могу увидеть контент и получить желаемый json. Единственная разница - @JsonView(EntityVisibility.Public.class) в class Response<T>, но я думаю, что у вас также есть это, потому что вы будете получать пустой объект, иначе

Вот демонстрационный проект. Можете ли вы протестировать устройство на своем устройстве или указать мне другую настройку.

import com.fasterxml.jackson.annotation.JsonIgnore; 
import com.fasterxml.jackson.annotation.JsonInclude; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.annotation.JsonView; 
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.web.bind.annotation.*; 
import java.util.*; 

@SpringBootApplication 
public class Application { 

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

    public static class EntityVisibility { 
     public static class Public { } 
     public static class Detailed extends Public { } 
     public static class Internal extends Detailed { } 
    } 

    @RestController 
    public static class MyRestController { 

     @JsonView(EntityVisibility.Public.class) 
     @RequestMapping(value="/", method= RequestMethod.GET) 
     public Response<Photo> loadFromUrl() { 

      Photo photo = new Photo(); // create photo object 
      photo.setB64content("dfgsdfgsdfg"); 
      photo.setMime_type("image/png"); 
      System.out.println(photo); 
      return new Response<>(photo); 
     } 
    } 


    @JsonInclude(JsonInclude.Include.NON_NULL) 
    public static class Response<T> { 
     @JsonView(EntityVisibility.Public.class) 
     private T result; 

     @JsonView(EntityVisibility.Public.class) 
     private boolean success = true; 

     @JsonView(EntityVisibility.Public.class) 
     private Object error; 

     @JsonView(EntityVisibility.Public.class) 
     private String errorCode; 

     @JsonView(EntityVisibility.Public.class) 
     private String message; 

     public T getResult() { 
      return result; 
     } 

     public void setResult(T result) { 
      this.result = result; 
     } 

     public Response(T response) { 
      result = response; 
     } 

     public boolean isSuccess() { 
      return success; 
     } 

     public void setSuccess(boolean success) { 
      this.success = success; 
     } 

     public Object getError() { 
      return error; 
     } 

     public void setError(Object error) { 
      this.error = error; 
     } 

     public String getErrorCode() { 
      return errorCode; 
     } 

     public void setErrorCode(String errorCode) { 
      this.errorCode = errorCode; 
     } 

     public String getMessage() { 
      return message; 
     } 

     public void setMessage(String message) { 
      this.message = message; 
     } 
    } 

    public static class Photo extends Entity { 

     @JsonIgnore 
     protected byte[] content; 

     @JsonView(EntityVisibility.Public.class) 
     private Date modified; 

     @JsonView(EntityVisibility.Public.class) 
     private String mime_type; 

     @JsonProperty("content") 
     @JsonView(EntityVisibility.Internal.class) 
     public void setB64content(String b64content) { 
      this.content = (b64content == null) ? null : b64content.getBytes(); 
     } 

     public String getB64content() { 
      return (content.length == 0) ? null : Base64.encode(content); 
     } 

     public byte[] getContent() { 
      return content; 
     } 

     public void setContent(byte[] content) { 
      this.content = content; 
     } 

     public Date getModified() { 
      return modified; 
     } 

     public void setModified(Date modified) { 
      this.modified = modified; 
     } 

     public String getMime_type() { 
      return mime_type; 
     } 

     public void setMime_type(String mime_type) { 
      this.mime_type = mime_type; 
     } 

     @Override 
     public String toString() { 
      return "Photo{" + 
        "content=" + Arrays.toString(content) + 
        ", modified=" + modified + 
        '}'; 
     } 
    } 

    @JsonInclude(JsonInclude.Include.NON_NULL) 
    public static class Entity { 

    } 
} 

Результат на 127.0.0.1:8080 является:

{ 
    "result": { 
    "mime_type": "image/png" 
    }, 
    "success": true 
} 
+0

Благодарим вас за подробный ответ. Однако на моей стороне должно быть что-то принципиально нарушенное. У меня нет '@JsonView (EntityVisibility.Public.class)' в классе Response, и я все еще вижу все. – kkazakov

+0

Я обновил начальную запись с новой информацией, включая файл pom.xml, но она по-прежнему не работает для меня. Я действительно не знаю, что происходит. В консоли нет ошибок. – kkazakov

+0

@kkazakov hm, это странно, потому что он по-прежнему работает для меня с вашей настройкой: https://github.com/varren/spring-jackson-JsonView вот демо. Единственное отличие, которое я сделал, это удалить ', предоставленный' от зависимости от tomcat, чтобы он мог запускаться. Я также добавил базовую конфигурацию 'WebSecurity', чтобы отключить проверку безопасности для'/test', и я не думаю, что часть безопасности может иметь inpact. И все-таки пришлось использовать @JsonView (EntityVisibility.Public.class) в классе Response – varren

Смежные вопросы