Spring MVC 3.1 RESTful Controller

时间:2012-10-09 10:52:25

标签: spring rest java-ee

我即将编写一个Spring MVC Controller来提供/接收HTML表单和JSON。最好的方法似乎是使用RESTful控制器,但作为我写的第一个我想做的正确!

是否有可能有一个方法返回一个视图,如果它是一个HTML请求,则返回由InternalResourceViewResolver呈现的视图,或者如果它是一个ajax请求,则返回一个呈现为JSON的实体?

同样适用于更新,您是否可以编写单个控制器方法,该方法将接受从传入JSON转换的对象或HTML表单中的@Valid对象,具体取决于内容类型?

在我看来你必须能够,否则为什么使用sf taglib表单元素支持HTML表单中的DELETE和PUT?似乎无法找到解释如何在任何地方做到这一点!

干杯! NFV

2 个答案:

答案 0 :(得分:1)

我会放手一搏。

以下是我在Configuration课程中的内容:

@Bean(name = "viewResolver")
public ContentNegotiatingViewResolver viewResolver() {
    final ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
    contentNegotiatingViewResolver.setOrder(1);
    contentNegotiatingViewResolver.setFavorPathExtension(true);
    contentNegotiatingViewResolver.setFavorParameter(true);
    contentNegotiatingViewResolver.setIgnoreAcceptHeader(false);
    final Map<String, String> mediaTypes = new HashMap<String, String>();
    mediaTypes.put("json", "application/x-json");
    mediaTypes.put("json", "text/json");
    mediaTypes.put("json", "text/x-json");
    mediaTypes.put("json", "application/json");
    mediaTypes.put("xml", "text/xml");
    mediaTypes.put("xml", "application/xml");
    contentNegotiatingViewResolver.setMediaTypes(mediaTypes);
    final List<View> defaultViews = new ArrayList<View>();
    defaultViews.add(jsonView());
    defaultViews.add(xmlView());
    contentNegotiatingViewResolver.setDefaultViews(defaultViews);
    return contentNegotiatingViewResolver;
}

@Bean(name = "xStreamMarshaller")
public XStreamMarshaller xStreamMarshaller() {
    return new XStreamMarshaller();
}

@Bean(name = "xmlView")
public MarshallingView xmlView() {
    final MarshallingView marshallingView = new MarshallingView(xStreamMarshaller());
    marshallingView.setContentType("application/xml");
    return marshallingView;
}

@Bean(name = "jsonView")
public MappingJacksonJsonView jsonView() {
    return new MappingJacksonJsonView();
}

以下是Controller中的内容。

@RequestMapping(value = { "/pets" }, method = RequestMethod.GET)
public String list(Model model) {
    model.addAttribute("pets", petRepository.findAll());
    return "pets/list";
}

@RequestMapping(value = { "/pets" }, method = RequestMethod.POST)
public String create(@Valid @RequestBody Pet pet, Model model) {
    petRepository.save(pet);
    return "redirect:pets/read/" + pet.getId();
}

@RequestMapping(value = { "/pets/{petId}" }, method = RequestMethod.GET)
public String read(@PathVariable Integer petId, Model model) {
    model.addAttribute("pet", petRepository.findOne(petId));
    return "pets/read";
}

@RequestMapping(value = { "/pets" }, method = RequestMethod.PUT)
public String update(@Valid @RequestBody Pet pet, Model model) {
    petRepository.save(pet);
    return "redirect:pets/read/" + pet.getId();
}

@RequestMapping(value = { "/pets/{orderId}" }, method = RequestMethod.DELETE)
public void delete(@PathVariable Integer petId, Model model) {
    petRepository.delete(petId);
}

根据我的经验,您可以将HTML表单或JSON对象作为@RequestBody提交。试一试。

答案 1 :(得分:0)

这肯定是可能的,但我不明白为什么那会有用。

在我的操作中,应该为您需要的每个动作创建一个控制器方法,使控制器处理2种不同类型的输入将使该控制器方法随着时间的推移而变得复杂。

这样做的方法是使用像这样的@RequestMapping注释中的消耗,然后你编写2个方法,每个方法都会监视它的输入。

@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json");

source of this code