泽西1。与Jackson的x:定制响应JSON。

时间:2021-09-20 18:02:54

I am using Jersey 1.19 to implement a rest api and Jackson to provide JSON support. My resource entities are deeply nested and I want to flatten them out before sending them over. I also want to provide support for filtering based on query params. Example GET /users/1234 returns the whole user resource while GET /users/1234?filter=username,email will return the user resource with only the given fields included.

我使用Jersey 1.19实现rest api和Jackson提供JSON支持。我的资源实体是深度嵌套的,我想在发送它们之前将它们变平。我还想提供基于查询解析的过滤支持。例如GET /users/1234返回整个用户资源,而GET /users/1234?过滤器=用户名,电子邮件将返回只包含给定字段的用户资源。

The approach I have currently taken is a subclass of JsonSerializer which flattens the hierarchy, but cannot handle parameter based filtering as it is independent of the request/response cycle. Google search pointed me to MessageBodyWriter. Looks like what I need but the writeTo method which handles the serializing doesn't take any parameter that would let me access the request, and hence the query params. So I am confused how to access those params in this method.

我目前采用的方法是JsonSerializer的一个子类,它可以扁平化层次结构,但是不能处理基于参数的过滤,因为它独立于请求/响应周期。谷歌搜索帮我找到了MessageBodyWriter。看起来像我所需要的,但是处理序列化的writeTo方法没有任何参数允许我访问请求,因此是查询参数。所以我不知道如何在这个方法中访问这些参数。

Any ideas are welcome

任何想法是受欢迎的

2 个解决方案

#1


1  

So I am confused how to access those params in this method.

所以我不知道如何在这个方法中访问这些参数。

You can inject UriInfo with @Context into the MessageBodyWriter. Then call uriInfo.getQueryParameter() to get the params. For example

您可以在MessageBodyWriter中使用@Context注入uri信息。然后调用uriInfo.getQueryParameter()获取参数。例如

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class YourWriter implements MessageBodyWriter<Something> {

    @Context UriInfo uriInfo;

    ...
    @Override
    public void writeTo(Something t, Class<?> type, Type type1, Annotation[] antns, 
            MediaType mt, MultivaluedMap<String, Object> mm, OutputStream out) 
            throws IOException, WebApplicationException {

        String filter = uriInfo.getQueryParameters().getFirst("filter");
    } 
}

Another option is to use a ContextResolver and use preconfigured ObjectMappers for different scenarios. You can also inject the UriInfo into the ContextResolver. For example

另一种选择是使用上下文解析器,并针对不同的场景使用预先配置的ObjectMappers。您还可以将UriInfo插入到上下文解析器中。例如

#2


0  

You should be able to pass a list in and/or you can expose the Request object if you want to go that route.

您应该能够传入一个列表,并且/或者如果您想要访问该路径,您可以公开请求对象。

Try ...

试一试……

@Context
UriInfo uriInfo;
@Context
HttpServletRequest request;

or try altering your Rest method to something like...

或者尝试改变你的休息方式,比如……

@GET
@Path("/myMethodLocator")
@Consumes(MediaType.APPLICATION_JSON)
...
public <whatever type you are returning> myMethod(List<String> filterByList) ...
...

#1


1  

So I am confused how to access those params in this method.

所以我不知道如何在这个方法中访问这些参数。

You can inject UriInfo with @Context into the MessageBodyWriter. Then call uriInfo.getQueryParameter() to get the params. For example

您可以在MessageBodyWriter中使用@Context注入uri信息。然后调用uriInfo.getQueryParameter()获取参数。例如

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class YourWriter implements MessageBodyWriter<Something> {

    @Context UriInfo uriInfo;

    ...
    @Override
    public void writeTo(Something t, Class<?> type, Type type1, Annotation[] antns, 
            MediaType mt, MultivaluedMap<String, Object> mm, OutputStream out) 
            throws IOException, WebApplicationException {

        String filter = uriInfo.getQueryParameters().getFirst("filter");
    } 
}

Another option is to use a ContextResolver and use preconfigured ObjectMappers for different scenarios. You can also inject the UriInfo into the ContextResolver. For example

另一种选择是使用上下文解析器,并针对不同的场景使用预先配置的ObjectMappers。您还可以将UriInfo插入到上下文解析器中。例如

#2


0  

You should be able to pass a list in and/or you can expose the Request object if you want to go that route.

您应该能够传入一个列表,并且/或者如果您想要访问该路径,您可以公开请求对象。

Try ...

试一试……

@Context
UriInfo uriInfo;
@Context
HttpServletRequest request;

or try altering your Rest method to something like...

或者尝试改变你的休息方式,比如……

@GET
@Path("/myMethodLocator")
@Consumes(MediaType.APPLICATION_JSON)
...
public <whatever type you are returning> myMethod(List<String> filterByList) ...
...