В контексте SpringMVC, как иметь веб-сервисы, которые предоставляют разные представления JSON одного и того же класса? - PullRequest
0 голосов
/ 24 мая 2018

У меня есть класс данных, что-то вроде этого:

public class Person {
   private String name;
   private Long code;

   // corresponding getters and setters
}

Я хочу написать два веб-сервиса, которые предоставляют два разных представления JSON Person.Например, один из них обеспечивает {"name":"foo"}, а другой {"name":"foo", "code":"123"}.

В качестве более сложного сценария предположим, что Person имеет ссылочное свойство, например адрес.У Address тоже есть свои свойства, и я ожидаю, что оба моих веб-сервиса учитывают это свойство, но каждый из них делает это по-своему.

Какими должны быть мои представления SpringMVC?

Обратите внимание, что я новичок в SpringMVC.Так что дайте мне пример кода рядом с вашим ответом, пожалуйста.

ОБНОВЛЕНИЕ 1: Через несколько дней все ответы подталкивают меня к решению проблемы в контроллерах или аннотировании классов данных.Но я хочу сделать это в представлениях, без каких-либо Java-кодов.Могу ли я сделать это в файлах JSP или шаблонах тимелиста или даже в файлах .properties?

ОБНОВЛЕНИЕ 2: Я нашел json-taglib .Но почему-то это не входит в новые обновления.Есть ли подобное решение?

Ответы [ 6 ]

0 голосов
/ 31 мая 2018

Я рекомендую вам использовать JSON.stringify (value [, replacer [, space]]) функцию во внешнем интерфейсе.Я привел пример ниже.У вас есть написать пользовательскую функцию в соответствии с вашими требованиями в конкретном представлении.

Например.В приведенном ниже примере игнорируются нулевые значения.Здесь я написал функцию editperson, которая удаляет нулевые значения.

Функция имеет два входных параметра: ключ и значение.Напишите свою логику в соответствии с ключами и значениями, которые вы хотите удалить или изменить.

var springperson = { "name":"foo","code":null }

console.log(springperson); // person recieved from  spring


function editjson(key, value){
if (value !== null) return value
}

var editperson = JSON.stringify(springperson, editjson); // String representation of person

var personjson=JSON.parse(editperson);  // JSON object representation of person

console.log(personjson); // person as required by the view

Прокомментируйте, если у вас есть какие-либо вопросы.

0 голосов
/ 31 мая 2018

При создании JSon с Spring MVC «визуализатором представления» по умолчанию является Джексон.Нет необходимости использовать такие вещи, как JSP или другие технологии просмотра.Что вы хотите сделать, это сказать Джексону, как визуализировать объект для данной ситуации.Доступно несколько вариантов, но я бы предложил использовать прогнозы.Пример:

@RestController
@RequestMapping(value = "person")
public class PersonController {

    private final ProjectionFactory projectionFactory;

    public PersonController(ProjectionFactory projectionFactory) {
        this.projectionFactory = projectionFactory;
    }

    @GetMapping("...")
    public PersonBase getPerson(..., @RequestParam(value = "view", required = false, defaultValue = "base") String view) {
        ...

        if(view.equals("extended")) {
            return projectionFactory.createProjection(PersonExtended.class, person);
        } else {
            return projectionFactory.createProjection(PersonBase.class, person);
        }
    }
}



public interface PersonBase {
    String getName();
}

public interface PersonExtended extends PersonBase {
    Long getCode;
}

Уровень представления вашего приложения - это проекционные классы (поместите их в один пакет, если хотите, в пакет просмотра).Контроллер может выбрать, какое представление будет отображаться, или вы можете сделать результат динамическим, как в примере.

Ваш вопрос о том, как отобразить адрес, можно решить с помощью другой проекции, подобной этой:

public interface PersonWithAddress extends PersonExtended {
    AddressProjection getAddress();
}

public interface AddressProjection {
    String getStreetName();
    String getZipcode();
    ...
}
0 голосов
/ 28 мая 2018

В зависимости от вашего варианта использования, просто вызовите контроллер по вашему выбору со страницы jsp / js ... Например, допустим, что Admin - это пользователь, затем вызовите AdminController, иначе вызовите User Controller ... это можно сделать с помощью простогоусловие if / else ... вы также можете посмотреть в Proxy Design Pattern, но это зависит от варианта использования

0 голосов
/ 28 мая 2018

Используйте Projection для представления вашего json различными способами и ResourceProcessor, если вам нужно добавить дополнительную информацию к этой модели через проекцию, например, другую таблицу БД.

0 голосов
/ 26 мая 2018

Вы можете искать динамическую фильтрацию полей, используя MappingJacksonValue.

Фильтр позволяет сериализовать поля, которые соответствуют пользовательским критериям.

Вы можете проверить мой пример кода здесь:

package com.github.tddiaz.jsonresponsefiltering;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import jdk.nashorn.internal.objects.annotations.Getter;
import lombok.Data;
import lombok.NonNull;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class Application {

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

    @RestController
    class Controller {

        @GetMapping("/filter")
        public ResponseEntity filter() {
            final Response response = new Response("value1", "value2", "value3");

            //ignore field3; will only return values of field1 and field2
            final SimpleBeanPropertyFilter beanPropertyFilter = SimpleBeanPropertyFilter.filterOutAllExcept("field1", "field2");

            final FilterProvider filterProvider = new SimpleFilterProvider().addFilter("responseFilter", beanPropertyFilter);

            final MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(response);
            mappingJacksonValue.setFilters(filterProvider);

            return ResponseEntity.ok(mappingJacksonValue);
        }
    }

    @JsonFilter("responseFilter")
    @Data
    class Response {
        @NonNull
        private String field1, field2, field3;
    }
}
0 голосов
/ 24 мая 2018

Вы используете Spring-MVC, поэтому Джексон отвечает за JSON сериализацию и десериализацию.

В этом случае вы можете использовать @JsonInclude(Include.NON_NULL), чтобы игнорировать пустое поле во время сериализации.

public class Person {
   @JsonInclude(Include.NON_NULL)
   private String name;

   @JsonInclude(Include.NON_NULL)
   private Long code;

   // corresponding getters and setters
}

Если ваш name или code равен null, то он исключается из вывода JSON

Так что если вы передадите code как null, ваш выходной JSON будет выглядетькак {"name":"foo"}

...