简述@Autowired和@Service
为了能被作为依赖注入,相应的类需要打上@Service
注解。然后通过注解@Autowired
到字段或方法,可以将相应的对象注入到Spring MVC控制器。
一般来说,类似于Struts2的情形,控制器动作处理函数(相当于Struts2的Action)需要调用服务层的方法来实现业务,就往往需要组合一个服务层类的对象,或将其作为参数传入,这时就可以用Spring做依赖注入了(在S2SH里也是这样做的)。@Service
注解打给Service层,语义上就很清楚。
服务层往往单独放在一个包下,它们需要被用来做DI,所以也需要被扫描到,和@Controller
注解一样,在Spring MVC配置文件中使用
<context:component-scan base-package="包路径"/>
来为需要打上@Service
注解的那些类配置级联扫描,它们将被注册为bean。
重定向
转发不会改变URI,纯粹是服务端的工作;重定向则相当于让客户端重新向一个服务器资源发出请求,会经过客户端,速度没有转发快。
提交表单后往往要让用户重定向到一个不同的页面,在基于注解的Spring MVC动作处理函数中,String类型的返回值形如
return "redirect:/.../";
即是在做重定向,而不是转发了。
Flash属性
重定向经过客户端,所以Model对象中的内容都会在重定向时丢失,可以使用Flash属性供重定向传值。
类似于Model对象的使用,使用Flash属性时需要为动作处理函数加上一个RedirectAttributes
类型的对象作为参数之一,并在return前使用该对象的addFlashAttribute(String ..,Object ..)
方法将重定向key和要使用的对象传入。
请求参数和路径变量
它们都是URL的一部分,用来发送值给服务器。
请求参数和@RequestParam
请求参数以
...?key1=value1&key2=value2&...
的形式在URL中出现。
在传统Servlet中可以用
httpServletRequest.getParameter("请求参数key");
的方式来获取其value值,这时就需要给动作处理方法添加一个HttpServletRequest
参数。
一种直接的方法是,为动作处理方法添加一个@RequestParam
注解的参数,参数的名称就是请求参数的key。如要获得传来的”stuId”,则可以在动作处理方法中添加
@RequestParam int stuId
至参数表。它所注解的参数类型不一定是字符串,Spring MVC会尽力做转换。
路径变量和@PathVariable
路径变量以
/.../路径变量
的形式出现,其中路径变量前面的URL中也可以有路径变量。
在动作处理函数的@RequestMapping
注解中可以看到路径变量的影子,因为它使URL变得不确定,但保持了一定的格式,例如添加指定id的学生:
@RequestMapping(value = "/add/{stuId}")
在其后的动作处理函数中添加一个与此处同名的变量作为参数,并添加@PathVariable
注解修饰。如要获得传来的”stuId”,则可以在动作处理方法中添加
@PathVariable int stuId
至参数表。类似地,它所注解的参数类型不一定是字符串,Spring MVC会尽力做转换。
@ModelAttribute
Spring MVC每次调用请求处理方法都会创建一个Model实例,如要使用则可以将其添加到形参,而@ModelAttribute
注解可以简化对该Model实例的使用。
将输入的或创建的参数对象添加到Model对象
在请求处理方法中为参数表中的某个参数添加@ModelAttribute
注解,则该参数对象会被添加到Model对象中。
如使用
@ModelAttribute Student stu
则相当于做了
model.addAttribute("student",stu);
如使用
@ModelAttribute("mystu") Student stu
则相当于做了
model.addAttribute("mystu",stu);
修饰非请求方法,以在动作前添加
这是一个好用的特性,控制器类可以有若干的请求处理方法,用@ModelAttribute
修饰方法时,则该方法成为一个非请求方法。
在调用该控制器类任意的请求处理方法之前会调用@ModelAttribute
修饰的方法,因此在该方法中完全可以出现@RequestParam
或者@PathVariable
修饰的参数,不过最重要的就是两件事:
①它会在任意请求处理方法之前被调用。
②当它有返回值时,返回的对象会自动添加到Model中;当它没有返回值时,可以为其添加一个Model类型参数,然后显式添加(就像在请求处理方法中那样)。
当然,所添加的Model指的是那个请求处理方法的Model,这样很多共同的操作以及总是需要显示的对象可以单独写这样一个@ModelAttribute
修饰的非动作处理方法。