Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring控制器由组合而不是继承组成_Java_Spring_Rest_Spring Mvc - Fatal编程技术网

Java Spring控制器由组合而不是继承组成

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

我开发了基于SpringMVC的REST应用程序

我有以下层次的控制器:

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类的专门处理
...
返回视图名;
}
...
}

示例取自实际程序,这就是为什么您可以看到分页、错误处理和访问底层请求的元素。

以下是可能的方法:

  • 使用
  • 使用
  • 使用(看起来比1和2更丑)
  • 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;
        }
        ...
    }