所以我有一个工作的 Spring MVC 3 应用程序,它带有一层服务,我需要将其转换为一层 RESTful Web 服务。
经过一些研究,我发现使用注释来做 GET Web 服务真的很容易。但是我仍然无法从 Java 以外的其他东西中找到相关的 POST 示例。
所以,为了让事情变得“简单”,让我们使用这个通用控制器:
public abstract class GenericControllerImpl<T, F extends GenericForm> implements GenericController<T, F> {
protected String name;
protected String root;
protected GenericService<T, F> service;
public GenericControllerImpl(final String root, final String name, final GenericService<T, F> service) {
this.root = root;
this.name = name;
this.service = service;
}
@Override
@RequestMapping(method = RequestMethod.GET)
public String defaultHome(final Model model) {
this.loadEntities(model);
this.populateLists(model);
return this.root;
}
@Override
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String display(@PathVariable final int id, final Model model) {
this.loadEntityContext(model, id);
return "display" + this.name;
}
@Override
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String displayCreate(final Model model) {
this.loadCreateContext(model);
this.populateLists(model);
return "create" + this.name;
}
@Override
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String createAction(@Valid @ModelAttribute("createForm") final F form, final BindingResult result, final Model model) {
try {
if (!result.hasErrors()) {
this.service.create(form);
return "redirect:/" + this.root + '/';
} else {
this.populateLists(model);
return "create" + this.name;
}
} catch (final Exception exception) {
this.populateLists(model);
this.loadErrorContext(model, exception);
return "create" + this.name;
}
}
@Override
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public String deleteAction(final Model model, @RequestParam(value = "id", required = true) final int id) {
try {
this.service.deleteFromId(id);
return "redirect:/" + this.root + '/';
} catch (final Exception exception) {
this.loadErrorContext(model, exception);
return this.root;
}
}
/**
* Load all the entities of the entity type handled by the controller into the context model.
*
* @param model
* the context model
*/
protected void loadEntities(final Model model) {
model.addAttribute("list", this.service.list());
}
/**
* Load a specific entity into the context model.
*
* @param model
* the context model
* @param id
* the id of the entity to load
*/
protected T loadEntity(final Model model, final int id) {
T item = this.service.findById(id);
model.addAttribute("item", item);
return item;
}
/**
* Load a specific entity context into the context model. By default it loads only the entity but for some entities, some other
* entities might be useful.
*
* @param model
* the context model
* @param id
* the id of the entity to load
*/
protected void loadEntityContext(final Model model, final int id) {
this.loadEntity(model, id);
}
/**
* Populate the lists of the other entities referenced by the current entity.
*
* @param model
* the context model
*/
protected abstract void populateLists(Model model);
}
所以一个简单的方法,比如display
会给出这样的东西(如果我明白了):
@Override
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
public T display(@PathVariable final int id) {
return this.service.findById(id);
}
但是我怎么能改变方法createAction
呢?
请注意,这是所有控制器都扩展的通用控制器。如果可以保持这种状态,那就太棒了,但如果不可能,那么我当然会做需要做的事情。
谢谢!