この問題はSpring-Dataリリース2で発生しました。最新バージョン1.13.9(およびそれ以前)では問題なく動作します。
コントローラーコード:
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
@RequestMapping(value = "sorttest", method = RequestMethod.GET)
public Page<Integer> getDummy() {
return new PageImpl<>(Collections.singletonList(1), new PageRequest(0, 5, new Sort("asdf")), 1);
}
}
Spring-Data 2スタイルにも同じ:
Pageable pageable = PageRequest.of(0, 10, new Sort(Sort.Direction.ASC, "asd"));
PageImpl<Integer> page = new PageImpl<Integer>(Lists.newArrayList(1,2,3), pageable, 3);
return page;
構成:
@SpringBootApplication
@EnableWebMvc
@EnableSpringDataWebSupport
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
また、Java構成とXML構成を使用して、Spring Bootを使用しない単純なSpringアプリケーションを試しました。結果は同じです。
{
"content": [
1
],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false
},
"offset": 0,
"pageSize": 5,
"pageNumber": 0,
"paged": true,
"unpaged": false
},
"totalElements": 1,
"last": true,
"totalPages": 1,
"size": 5,
"number": 0,
"sort": {
"sorted": true,
"unsorted": false
},
"numberOfElements": 1,
"first": true
}
Spring-Dataのバージョンを1.Xに変更すると、オブジェクトをソートするための正しいJSON応答が得られます。
{
"content": [
1
],
"totalElements": 1,
"totalPages": 1,
"last": true,
"size": 5,
"number": 0,
"sort": [
{
"direction": "ASC",
"property": "asdf",
"ignoreCase": false,
"nullHandling": "NATIVE",
"ascending": true,
"descending": false
}
],
"numberOfElements": 1,
"first": true
}
私はすべてを試したようですが、変更ログでソートの変更に関する通知が見つかりませんでした。SpringJIRAでそのような問題は見つかりませんでした。
したがって、問題は、次のような並べ替えでどのようにspring-data 2.X libs JSONを取得するかです。
"sort": [
{
"direction": "ASC",
"property": "asdf",
"ignoreCase": false,
"nullHandling": "NATIVE",
"ascending": true,
"descending": false
}
]
の代わりに:
"sort": {
"sorted": true,
"unsorted": false
}
私はあなたと同じ問題に遭遇し、あなたの返答は役に立ちましたが、ここで私は最も短い答えを提供します。
あなたが言ったように、Sortクラスのカスタムシリアライザを作成する必要があります。
しかし、必要なのは、JsonSerializerクラスに@JsonComponent
ジャクソンに登録します。
ソリューション
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.data.domain.Sort;
import Java.io.IOException;
@JsonComponent
public class SortJsonSerializer extends JsonSerializer<Sort> {
@Override
public void serialize(Sort value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartArray();
value.iterator().forEachRemaining(v -> {
try {
gen.writeObject(v);
} catch (IOException e) {
e.printStackTrace();
}
});
gen.writeEndArray();
}
@Override
public Class<Sort> handledType() {
return Sort.class;
}
}
参照
カスタムシリアライザを追加する問題を解決しました。
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.data.domain.Sort;
import Java.io.IOException;
public class SortJsonSerializer extends JsonSerializer<Sort> {
@Override
public void serialize(Sort orders, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartArray();
orders.iterator().forEachRemaining(o -> {
try {
jsonGenerator.writeObject(o);
} catch (IOException e) {
e.printStackTrace();
}
});
jsonGenerator.writeEndArray();
}
@Override
public Class<Sort> handledType() {
return Sort.class;
}
}
また、Springを使用するには、extendMessageConvertersをオーバーライドします。
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.xxx.ws"})
@EnableSpringDataWebSupport
public class SpringWebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
SortHandlerMethodArgumentResolver sortResolver = new SortHandlerMethodArgumentResolver();
// For sorting resolution alone
argumentResolvers.add(sortResolver);
PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver(sortResolver);
pageableResolver.setMaxPageSize(10000);
// For sorting resolution encapsulated inside a pageable
argumentResolvers.add(pageableResolver);
argumentResolvers.add(new CurrentUserArgumentResolver());
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
SimpleModule module = new SimpleModule();
module.addSerializer(Sort.class, new SortJsonSerializer());
return new Jackson2ObjectMapperBuilder()
.findModulesViaServiceLoader(true)
.modulesToInstall(module);
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//First converters added in WebMvcConfigurationSupport.addDefaultHttpMessageConverters and then we add our behaviour here
Jackson2ObjectMapperBuilder builder = jackson2ObjectMapperBuilder();
for (int i=0; i<converters.size(); i++) {
if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
converters.set(i, new MappingJackson2HttpMessageConverter(builder.build()));
}
}
}
}