原理:
用户发送请求(user.do)给服务器,服务器收到请求后,发现DispatchServlet可以处理,于是调用DispatchServlet,DispatchServlet内部通过HandleMapping检查这个请求有没有对应的Controller,如果有,则调用Controller。Controller开始执行,执行完后,如果返回字符串,则ViewResolver将字符串转化成相应的视图对象,如果返回ModelAndView对象,该对象本身就包含了视图对象信息,DispatchServlet将视图对象中的数据输出给服务器,服务器将数据输出给客户端。
注解:
1.@Controller
和struts1一样,spring的Controller也是Singleton的。这就意味着会被多个请求线程共享。因此,我们将控制器设计成无状态类。在spring 3.0中,通过@controller标注即可将class定义为一个controller类。为使spring能找到定义为controller的bean,需要在spring配置文件中增加组件扫描标签:<context:component-scan base-package="xxx.yyy.zzz"/>,实际上,使用@component,也可以起到@Controller同样的作用。
2.@RequestMapping
在类前面定义则将url和类绑定。在方法前面定义则将url和类的方法绑定,示例代码:
package com.test.controller;
import java.io.UnsupportedEncodingException;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.test.service.EmployeeService;
@Controller
@RequestMapping("/employee")
public class EmployeeController {
private EmployeeService employeeService;
public EmployeeService getEmployeeService() {
return employeeService;
}
@Resource(name = "employeeService")
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
//http://localhost:8080/springmvc/employee?method=request&name=xxx
@RequestMapping(params = "method=request")
public String request(String name) {
try {
employeeService.add(new String(name.getBytes("iso8859-1"), "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "result";
}
}
3.@RequestParam
一般用于将指定的请求参数付给方法中形参。示例代码:
@RequestMapping("/hello")
public String helloWorld(@RequestParam("id") int userId) {
System.out.println("userId=" + userId);
return "helloWorld";
}
这样就会将id参数的值付给userId。当然,如果请求参数名称和形参名称保持一致,则不需要这个注解。
4.@SessionAttributes
将Model中指定的属性放到session中。示例代码:
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Controller
@RequestMapping("/user")
// 表示loginUser是session属性
@SessionAttributes("loginUser")
public class UserController {
@RequestMapping(value = "/loginUser", method = RequestMethod.POST)
public String loginUser(String username, Model model) {
// 把登录用户名的信息保存到session的loginUser中,注意loginUser和上面@SessionAttributes中的参数保持一致
model.addAttribute("loginUser", username);
return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/user/userList";
}
}
5.@ModelAttribute
这个注解可以跟@SessionAttributes配合在一起用。可以将Model中属性的值通过该注解自动赋给指定变量。示例代码:
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Controller
@RequestMapping("/user")
// 表示loginUser是session属性
@SessionAttributes("loginUser")
public class UserController {
@RequestMapping(value = "/loginUser", method = RequestMethod.POST)
public String loginUser(String username, Model model) {
// 把登录用户名的信息保存到session的loginUser中,注意loginUser和上面@SessionAttributes中的参数保持一致
model.addAttribute("loginUser", username);
return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/user/userList";
}
@RequestMapping(value = "/loginUser2")
public String loginUser2(@ModelAttribute("loginUser") String username) {
// 先访问/user/loginUser,在访问/user/loginUser2
System.out.println(username);
return "xxx";
}
}
6.Controller类中方法返回值的处理
根据返回值找对应的显示页面。路径规则为:prefix前缀+返回值+suffix后缀组成,也可以返回ModelMap、ModelAndView、map、List、Set、Object、无返回值。一般建议返回字符串。
7.ModelAndView模型视图类
ModelAndView中的Model代表模型,View代表视图。即,这个类把要显示的数据存储到了Model属性中,要跳转的视图信息存储到了view属性。示例代码:
package com.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.test.model.User;
@Controller
public class UserController extends MultiActionController {
@RequestMapping("/test")
public ModelAndView test(String uname) {
ModelAndView mv = new ModelAndView();
mv.setViewName("index");
User u = new User();
u.setUsername("张三");
mv.addObject(u); // 属性名为首字母小写的类名,建议手动增加属性名称
mv.addObject("a", "aaaa");
return mv;
}
}