摘要
SpringMVC中,控制器Controller负责处理DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层之后封装成一个Model,然后再把该Model返回给对应的View进行展示。
一,简介
在SpringMVC中,控制层Controller负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理之后封装成一个Model,然后再把该Model返回给对应的View进行展示。在SpringMVC提供了一个非常简便的定义Controller的方法,你无须继承特定的类或实现特定的接口,只需使用@Controller标记一个类是Controller,然后使用@RequestMapping和@RequestParam等一些注解用定义URL请求和Controller方法之间的映射,这样的Controller就能被外界访问到。此外Controller不会直接依赖于HttpServletRequest和HttpServlet对象,它们可以通过Controller的方法参数灵活的获取到。为了先对Controller有一个初步的印象,以下先定义一个简单的Controller:
@Controller
public class MyController{
@RequestMapping("/showView")
public ModelAndView showView(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要方法model中的属性名称","对应的属性值,它是一个对象");
return modelAndView;
}
}
在上面的示例中,@Controller是标记在类MyController上面的,所以类MyController就是一个SpringMVC Controller对象了,然后使用@RequestMapping("/showView")标记在Controller方法上,表示请求/showView.do的时候访问的是MyController的showView方法,该方法返回了一个包括Model和View的ModelAndView对象,这些在后续都将会详细介绍。
二,使用@Controller定义一个Controller控制器
@Controller用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。@Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是真正处理请求的处理器,这个接下来就会讲到。
单单使用@Controller标记在一个类上还不能真正意义上的说它就是SpringMVC的一个控制器类,因为这个时候Spring还不认识它。那么要如何做Spring才能认识它呢?这个时候就需要我们把这个控制器类交给Spring来管理。拿MyController来举一个例子。
@Controller
public class MyController{
@RequestMapping("/showView")
public ModelAndView showView(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要方法model中的属性名称","对应的属性值,它是一个对象");
return modelAndView;
}
}
这个时候有俩种方式可以把MyController交给Spring管理,好让它能够识别我们标记的@Controller。
第一种方式是在SpringMVC的配置文件中定义MyController的bean对象。
<bean class="com.host.app.web.controller.MyController" />
第二种方式是在SpringMVC的配置文件中告诉Spring该到哪里去找标记为@Controller的Controller控制器。
<context:component-scan base-packag = "com.host.app.web.controller">
<context:exclude-filter type="annotation"
expression = "org.springframework.stereotype.Service" />
</context:component-scan>
上面Context:exclude-filter标注的是不扫描@Service标注的类。
三,使用@RequestMapping来映射Request请求与处理器
可以使用@RequestMapping来映射URL到控制器类,或者是到Controller控制器的处理方法上。当@RequestMapping标记在Controller类上的时候,里面使用@RequestMapping标记的方法的请求地址都是相对于类上的@RequestMapping而言的;当Controller类上没有标记@RequestMapping注解时,方法上的@RequestMapping都是绝对路径。这种绝对路径和相对路径组合合成的最终路径都是相对于跟路径"/"而言的。
@Controller
public class MyController{
@RequestMapping("/showView")
public ModelAndView showView(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要方法model中的属性名称","对应的属性值,它是一个对象");
return modelAndView;
}
}
在这个控制器中,因为MyController没有被@RequestMapping标记,所以当需要访问到里面使用了@RequestMapping标记的showView方法时,就是使用的绝对路径/showView.do请求就可以了。
@Controller
@RequestMapping("/test")
public class MyController{
@RequestMapping("/showView")
public ModelAndView showView(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要方法model中的属性名称","对应的属性值,它是一个对象");
return modelAndView;
}
}
这种情况是在控制器上加了@RequestMapping注解,所以当需要访问到里面使用了@RequestMapping标记的方法showView()的时候就需要showView方法上@RequestMapping相对于控制器MyController上@RequestMapping的地址,即/test/showView.do 。
@Controller
@RequestMapping("/test/{variable1}")
public class MyController{
@RequestMapping("/showView/{variable2}")
public ModelAndView showView(@pathVariable String variable, @pathVariable ("variable2") int variable2){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要方法model中的属性名称","对应的属性值,它是一个对象");
return modelAndView;
}
}
在上面的代码中我们定义了俩个URI变量,一个是控制器类上的variable1,一个是showView方法上的variable2,然后在showView方法的参数里面使用@PathVariable标记使用了这俩个变量。所以当我们使用/test/hello/showView2/2.do来请求的时候就可以访问到MyController的showView方法,这个时候variable1就被赋予值hello,variable2就被赋予值2,然后我们在showView方法参数里面标注了参数variable1和variable2是来自访问路径的path变量,这样方法参数variable1和variable2就被分别赋予hello和2。方法参数variable1是定义为String类型,variable2是定义为int类型,像这种简单类型在进行赋值的时候Spring是会帮我们自动转换的,关于复杂类型如何来转换在后续内容中将会讲到。