Java Spring控制器由组合而不是继承组成
我开发了基于SpringMVC的REST应用程序 我有以下层次的控制器:Java Spring控制器由组合而不是继承组成,java,spring,rest,spring-mvc,Java,Spring,Rest,Spring Mvc,我开发了基于SpringMVC的REST应用程序 我有以下层次的控制器: UserController extends ImageController ImageController extends SuggestController // Controller that has GET-DELETE-POST for image SuggestController extends CrudController// Controller that has some suggest meth
UserController extends ImageController
ImageController extends SuggestController // Controller that has GET-DELETE-POST for image
SuggestController extends CrudController// Controller that has some suggest methods
CrudController // CRUD operations
因此,我在runtume中有以下映射:
/users (POST-GET-PUT-DELETE)
/users/suggest (GET, POST(Spring Pageable))
/users/image (POST-GET-DELETE)
在我意识到之前一切正常,一个控制器必须能够给我它的东西的图像,但不能实现“建议”方法:
另一个没有“图像”功能,但有“建议”:
Java说:“在这种情况下使用组合”:
那么,在没有委托样板的情况下,我如何在春季MVC中实现这一点呢?注释?XML?Spring MVC将不允许您重写用@RequestMapping注释的方法,或者更确切地说,它不允许您用@RequestMapping注释重写方法,并将在基类中使用映射 但您总是可以在基类中定义两个方法:一个是用@RequestMapping注释的,它只委托给第二个未注释的方法。然后您就可以自由地重写子类中的第二个方法。例如: CRUD控制器的抽象基类
public abstract class AbstractCRUDController<K extends Serializable, X>
// X is the data class, K is the class of the key (int or String)
@RequestMapping({"/{data}"})
public String show(@ModelAttribute("data") X data, HttpSession session, Model model,
@RequestParam(value = "pagesize", required = false, defaultValue = "-1") int pageSize,
WebRequest request,
@RequestParam(value = "all", defaultValue = "false") boolean all) {
return doShow(data, session, model, pageSize, request, all);
}
protected String doShow(X data, HttpSession session, Model model,
int pageSize, WebRequest request, boolean all) {
return this.getPrefix() + "/view";
}
@RequestMapping(value={"/{data}/edit"}, method=RequestMethod.GET)
public String edit(@ModelAttribute("data") X data, Model model) {
return doEdit(data, model);
}
protected String doEdit(@ModelAttribute("data") X data, Model model) {
model.addAttribute("title", editTitle);
return this.getPrefix() + "/edit";
}
@RequestMapping(value={"/{data}/edit"}, method=RequestMethod.POST)
public String update(@ModelAttribute("data") X data, BindingResult result, Model model) {
if (data == null) {
throw new NoSuchElementException();
}
if (save(data, result, model, SimpleSaveType.UPDATE, null) != null) {
return "redirect:" + savedUrl(data);
}
else {
model.addAttribute("title", editTitle);
return getPrefix() + "/edit";
}
}
public K save(X data, BindingResult result, Model model, SaveType saveType, K id) {
...
}
...
public abstract String getPrefix();
}
公共抽象类AbstractCRUDController
//X是数据类,K是键的类(int或String)
@请求映射({/{data}})
公共字符串显示(@modeldattribute(“data”)X数据,HttpSession会话,模型模型,
@RequestParam(value=“pagesize”,required=false,defaultValue=“-1”)int pagesize,
WebRequest请求,
@RequestParam(value=“all”,defaultValue=“false”)布尔值全部){
返回doShow(数据、会话、模型、页面大小、请求、全部);
}
受保护字符串doShow(X数据、HttpSession会话、模型、,
int pageSize、WebRequest、boolean all){
返回此.getPrefix()+“/view”;
}
@RequestMapping(值={/{data}/edit},方法=RequestMethod.GET)
公共字符串编辑(@modeldattribute(“数据”)X数据,模型){
返回doEdit(数据、模型);
}
受保护的字符串doEdit(@ModelAttribute(“数据”)X数据,模型){
model.addAttribute(“标题”,editTitle);
返回此.getPrefix()+“/edit”;
}
@RequestMapping(值={/{data}/edit},方法=RequestMethod.POST)
公共字符串更新(@modeldattribute(“data”)X数据,BindingResult,Model模型){
如果(数据==null){
抛出新的NoTouchElementException();
}
if(保存(数据、结果、模型、SimpleSaveType.UPDATE、null)!=null){
返回“重定向:+savedUrl(数据);
}
否则{
model.addAttribute(“标题”,editTitle);
返回getPrefix()+“/edit”;
}
}
公共K保存(X数据、BindingResult结果、模型模型、保存类型、K id){
...
}
...
公共抽象字符串getPrefix();
}
类ProcessQ的具体实现
@Controller
@RequestMapping(ProcessController.PREFIX)
public class ProcessController extends AbstractCRUDController<Integer, ProcessQ> {
public static final String PREFIX = "/process";
@Override
public String getPrefix() {
return PREFIX;
}
@Override
protected String doShow(ProcessQ process, HttpSession session, Model model,
int pageSize, WebRequest request, boolean all) {
String viewName = super.doShow(process, session, model, pageSize, request, all);
// specialized processing for class ProcessQ
...
return viewName;
}
...
}
@控制器
@RequestMapping(ProcessController.PREFIX)
公共类ProcessController扩展AbstractCRUDController{
公共静态最终字符串前缀=“/process”;
@凌驾
公共字符串getPrefix(){
返回前缀;
}
@凌驾
受保护字符串doShow(ProcessQ进程、HttpSession会话、模型、,
int pageSize、WebRequest、boolean all){
字符串viewName=super.doShow(进程、会话、模型、页面大小、请求、全部);
//ProcessQ类的专门处理
...
返回视图名;
}
...
}
示例取自实际程序,这就是为什么您可以看到分页、错误处理和访问底层请求的元素。以下是可能的方法:
StuffController {
@InlineThisController
ImageController imagedController;
@InlineThisController
CrudController crudController;
... //some additional methods
}
public abstract class AbstractCRUDController<K extends Serializable, X>
// X is the data class, K is the class of the key (int or String)
@RequestMapping({"/{data}"})
public String show(@ModelAttribute("data") X data, HttpSession session, Model model,
@RequestParam(value = "pagesize", required = false, defaultValue = "-1") int pageSize,
WebRequest request,
@RequestParam(value = "all", defaultValue = "false") boolean all) {
return doShow(data, session, model, pageSize, request, all);
}
protected String doShow(X data, HttpSession session, Model model,
int pageSize, WebRequest request, boolean all) {
return this.getPrefix() + "/view";
}
@RequestMapping(value={"/{data}/edit"}, method=RequestMethod.GET)
public String edit(@ModelAttribute("data") X data, Model model) {
return doEdit(data, model);
}
protected String doEdit(@ModelAttribute("data") X data, Model model) {
model.addAttribute("title", editTitle);
return this.getPrefix() + "/edit";
}
@RequestMapping(value={"/{data}/edit"}, method=RequestMethod.POST)
public String update(@ModelAttribute("data") X data, BindingResult result, Model model) {
if (data == null) {
throw new NoSuchElementException();
}
if (save(data, result, model, SimpleSaveType.UPDATE, null) != null) {
return "redirect:" + savedUrl(data);
}
else {
model.addAttribute("title", editTitle);
return getPrefix() + "/edit";
}
}
public K save(X data, BindingResult result, Model model, SaveType saveType, K id) {
...
}
...
public abstract String getPrefix();
}
@Controller
@RequestMapping(ProcessController.PREFIX)
public class ProcessController extends AbstractCRUDController<Integer, ProcessQ> {
public static final String PREFIX = "/process";
@Override
public String getPrefix() {
return PREFIX;
}
@Override
protected String doShow(ProcessQ process, HttpSession session, Model model,
int pageSize, WebRequest request, boolean all) {
String viewName = super.doShow(process, session, model, pageSize, request, all);
// specialized processing for class ProcessQ
...
return viewName;
}
...
}