2012-10-09 55 views
2

林要寫一個Spring MVC的控制器來服務/接收HTML表單和JSON。最好的方式似乎是使用一個RESTful控制器,但作爲我寫的第一個我想要做的正確!Spring MVC的3.1 REST風格的控制器

是否有可能返回一個方法,如果它的HTML請求返回由InternalResourceViewResolver呈現的視圖,或者如果它的ajax請求將呈現爲JSON的實體?

同樣的更新,你可以編寫一個控制器方法,它將接受從傳入的JSON轉換而來的對象或來自HTML表單的@Valid對象,具體取決於內容類型?

我在我看來,你一定可以的,不然爲什麼對DELETE的支持和使用SF的taglib表單元素在HTML表單PUT?只是似乎無法找到解釋如何在任何地方做到這一點!

乾杯! NFV

回答

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。試一試。

+0

我試圖改變我的設置是這樣的,但只是不斷得到一個「HTTP狀態415 - 服務器拒絕這個請求,因爲請求實體的格式不被所請求的方法()所請求的資源支持」。如果我刪除@RequestBody註釋它工作正常(至少對於表單帖子) – nfvindaloo

+0

刪除'@ RequestBody'並查看HTML表單和JSON是否提交工作。我認爲Spring會爲你處理。無論哪種方式,當你只返回一個'String'時,Spring會將你反射到一個視圖(如果acceptType是HTML)或者將任何'Model'對象轉換爲JSON。 – sbzoom

+0

謝謝,生病了! – nfvindaloo

0

這是肯定可能,但我不明白爲什麼這將是有益的。

在我opnion控制器方法應該爲每個你將需要採取行動來創建,使控制器手柄2種不同的輸入將使複雜的閱讀和維護隨着時間的推移這種控制器的方法。

它在@RequestMapping註解這樣使用消耗做的一種方式,那麼你就寫2點的方法和各手錶它是一種投入。

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

source of this code

+0

我看,我認爲,框架會處理所有的轉換,以使實現簡單和烘乾機。你知道爲什麼我們可以選擇在表單請求中使用DELETE和PUT方法嗎?我曾假設它是這樣的,你可以使用HTML表單的相同處理方法,但也許我錯了! – nfvindaloo