2012-10-09 4 views
2

Я собираюсь написать Spring MVC Controller для обслуживания/получения HTML-форм и JSON. Лучшим способом, по-видимому, является использование контроллера RESTful, но поскольку его первый Ive написал, я хочу сделать это правильно!Spring MVC 3.1 RESTful Controller

Возможно ли иметь один метод, который будет возвращать либо представление, которое будет визуализироваться InternalResourceViewResolver, если его HTML-запрос, или объект, который будет отображаться как JSON, если он является ajax-запросом?

То же самое касается обновлений, можете ли вы написать один метод контроллера, который будет принимать либо объект, который был преобразован из входящего JSON или объекта @Valid из формы HTML, в зависимости от типа содержимого?

Мне кажется, вы должны уметь, в противном случае, у кого есть поддержка DELETE и PUT в HTML-формах, используя элемент формы sf taglib? Просто не могу найти объяснения, как это сделать в любом месте!

Cheers! 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

Ive попытался изменить мои настройки таким образом, но просто продолжайте получать «HTTP Status 415». Сервер отказал в этом запросе, поскольку объект запроса находится в формате, не поддерживаемом запрошенным ресурсом для запрошенного метода() ». Если я удалю аннотации @RequestBody, он отлично работает (по крайней мере для сообщений формы). – nfvindaloo

+0

Удалите '@ RequestBody' и посмотрите, поддерживает ли форма HTML и JSON. Я думаю, что Spring справится с этим для вас. В любом случае, когда вы возвращаете только «String» Spring, либо отскакивает от вас до представления (если acceptType является HTML), либо переводит любые объекты «Model» в JSON. – sbzoom

+0

Спасибо, плохо дайте это! – nfvindaloo

0

Это, конечно, возможно, но я не понимаю, почему это было бы полезно.

В моем варианте метод контроллера должен быть создан для каждого действия, которое вам понадобится, что делает ручку контроллера двумя разными видами ввода, что усложнит этот метод контроллера для чтения и обслуживания с течением времени.

Способ использования используется в комментариях @RequestMapping, подобном этому, тогда вы пишете 2 метода, и каждый из них наблюдает за его входом.

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

source of this code

+0

Я вижу, я думал, что структура будет обрабатывать все преобразования, чтобы упростить реализацию и DRYer. Знаете ли вы, почему у нас есть возможность использовать методы DELETE и PUT в запросах формы? Я предположил, что вы можете использовать те же методы обработчика для HTML-форм, но, возможно, я ошибаюсь! – nfvindaloo

Смежные вопросы