如何从Jersey资源生成JSON?

时间:2010-01-23 00:03:39

标签: java json rest jersey jackson

我正在使用Jersey并希望仅输出列出的字段输出以下JSON:

[
    {
      "name": "Holidays",
      "value": "http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic"
    },
    {
      "name": "Personal",
      "value": "http://www.google.com/calendar/feeds/myprivatefeed/basic"
    }
]

如果必须的话,我可以使用{“feeds”:...}来包围JSON,但是将其设为可选是最好的。我想从CalendarFeeds列表中提取这些信息,这些CalendarFeeds存储在通过Hibernate检索的Member POJO中。以下是简化的POJO:

public class Member {
    private String username;
    private String password;
    private Set<CalendarFeed> calendarFeeds = new HashSet<CalendarFeed>();
}

public class CalendarFeed {
    public enum FeedType { GCAL, EVENT };
    private Member owner;
    private String name;
    private String value;
    private FeedType type;
}

目前,我有一个名为CalendarResource的Jersey资源,它手动输出带有日历源信息的JSON:

@Path("/calendars")
public class CalendarResource {

    @Inject("memberService")
    private MemberService memberService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getCalendars() {
        // Get currently logged in member
        Member member = memberService.getCurrentMember();

        StringBuilder out = new StringBuilder("[");
        boolean first = true;
        for (CalendarFeed feed : member.getPerson().getCalendarFeeds()) {
            if (!first) {
                out.append(",");
            }
            out.append("{\"");
            out.append(feed.getName());
            out.append("\":\"");
            out.append(feed.getValue());
            out.append("\"}");
            first = false;
        }
        out.append("]");
        return out.toString();
    }
}

但我不确定如何实现自动化。我刚刚开始使用Jersey,并且不清楚如何使用它来返回JSON。听起来它有一种内置方式,但看起来我需要为我的POJO添加注释。另外,我读了其他人说我需要使用杰克逊。我一直在谷歌搜索,似乎无法找到一个从Jersey资源返回JSON的简单例子。有人知道吗?或者你能告诉我如何使用Jackson或Jersey为上面的例子创建JSON吗?

2 个答案:

答案 0 :(得分:8)

我想出了如何使用Jackson 1.4做到这一点。我没有使用jersey-json,因为它基于旧版本的Jackson而且我需要1.4版来使用JsonViews。

这是带注释的pojo:

public class CalendarFeed {
    public enum FeedType { GCAL, EVENT };
    @JsonIgnore
    private Member owner;
    private String name;
    private String value;
    @JsonIgnore
    private FeedType type;
}

这是球衣资源:

@Path("/calendar")
public class CalendarResource {

 @Inject("memberService")
 private MemberService memberService;

 @Inject
 private ObjectMapper mapper;

 @GET
 @Produces(MediaType.APPLICATION_JSON)
 public String getCalendars() {
  Member member = memberService.getCurrentMember();
  try {
   return mapper.writeValueAsString(member.getCalendarFeeds());
  } catch (JsonGenerationException e) {
  } catch (JsonMappingException e) {
  } catch (IOException e) {
  }
  return "{}";
 }
}

这是我的春豆:

<!-- Jackson JSON ObjectMapper -->
<bean id="objectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>

输出正是我所需要的。使用JsonViews,我可以自定义哪些字段可以输出不同的情况。

希望这会帮助别人!

答案 1 :(得分:6)

自从接受了答案后,这已经发生了变化。

如果打开pojoMappingFeature,则泽西将自动调用objectMapper。在servlet环境中,在您的球衣定义中执行以下操作:

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

您现在可以直接从端点返回Feed。

@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<CalendarFeeds> getCalendars() {
    Member member = memberService.getCurrentMember();
    return member.getCalendarFeeds();
}