1. B/S架构的MVC
MVC(Model View Controller):模型(model)、视图(view)、控制器(controller)是目前流行的一种开发模式。B/S架构的运行流程如下
- 用户(user)发起请求(request),控制器(controller)接收到用户请求,并将用户请求的数据委托给模型(model)
- 控制器通过模型(model)进行一系列的业务逻辑处理后,将处理结果再返回给控制器
- 控制器将模型返回的数据展示在视图(view)上
- 控制器将处理完成的结果视图返回给用户(response)
2. SpringMVC
架构图
-用户发送请求(request)至前端控制器DispatcherServlet
- DispatcherServlet收到请求后调用HandlerMapping处理器映射器查找处理器
- 处理器映射器找到具体的处理器后,生成处理器对象和处理器拦截器,并返回给DispatcherServlet
- DispatcherServlet调用HandlerAdapter处理器适配器
- HandlerAdapter经过适配调用具体的处理器(后端控制器)
- 处理器执行完成后返回ModelAndView
- HandlerAdapter将处理器的执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet根据View进行数据渲染,将模型中的数据填充至视图中
- DispatcherServlet将最后的视图返回给用户
3. 各个组件
- HandlerMapping处理器映射器
①、BeanNameUrlHandlerMapping
将后端控制器的beanName作为请求的url
<!—beanName Url映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
②、SimpleUrlHandlerMapping
通过后端控制器bean的id,可定义多个url映射至一个后端控制器,<prop></prop>中间的之为后端控制器bean的id
- ```
<!—简单url映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello1.action">hello_controller</prop>
<prop key="/hello2.action">hello_controller</prop>
</props>
</property>
</bean>
- HandlerAdapter处理器适配器
①、SimpleControllerHandlerAdapter
简单控制器器处理器适配器,所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean作为Springmvc的后端控制器。控制器返回ModelAndView
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
②、HttpRequestHandlerAdapter
HTTP请求处理器适配器,将http请求封装成HttpServletRequest和HttpServletResponse对象,和servlet接口类似,控制器通过response修改定义响应内容
- ```
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
- 控制器
实现Controller接口的bean,返回ModelAndView对象
<bean id="command_controller" name="/command.action"
class="com.snakotech.springmvc.controller"/>
4. 注解开发
4.1 一个例子
<!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
- Controller编写
- ```
@Controller
publicclass HelloWorldController {
@RequestMapping(value="/hello")
public String hello(Model model)throws Exception{
model.addAttribute("message", "HelloWorld!");
return"hello";
}
}
@Controller:用于标识处理类
@RequestMapping:请求到处理器功能方法的映射规则
在xml中的配置
<bean class="com.snakotech.springmvc.controller.HelloWorldController"/>
组件扫描:如果使用了组件扫描则不需要在xml中配置Controller
可扫描@component、@controller、@service、@repository的注解
<context:component-scan base-package="com.snakotech.springmvc.controller" />
#####4.2 @Controller和@RequestMapping
- @Controller
标识该类为控制类,@Controller、@Service、@Repository分别对应web应用三层架构的组件,控制器、服务接口、数据访问接口
- @RequestMapping
- - URL路径映射
@RequestMapping(value="/user")或@RequestMapping("/user")
- - 根路径和子路径
根路径:@RequestMapping放在类名上边
- - ```
@Controller
@RequestMapping("/user")
子路径:@RequestMapping放在方法名上边
@RequestMapping("/user")
public String userAdd() {}
- - URL模板模式映射@RequestMapping(value="/useredit/{userId}"):{×××}占位符,请求的URL可以是“/useredit/001”或“/useredit/abc”,通过在方法中使用@PathVariable获取{×××}中的×××变量。
- - ```
@RequestMapping("/useredit/{userid}")
public String useredit(@PathVariable String userid,Model model) throws Exception{
//方法中使用@PathVariable获取useried的值,使用model传回页面
model.addAttribute("userid", userid);
return"/user/useredit";
}
多个占位符
@RequestMapping("/useredit/{groupid}/{userid}")
public String useredit(@PathVariable String groupid,@PathVariable String userid,Model model) throws Exception{
//方法中使用@PathVariable获取useried的值,使用model传回页面
model.addAttribute("groupid", groupid);
model.addAttribute("userid", userid);
return"/user/useredit";
}
#####4.3 请求方法限定
- 限定GET方法
- ```
@RequestMapping(method = RequestMethod.GET)
如果通过Post访问则报错:
HTTP Status 405 - Request method 'POST' not supported
@RequestMapping(value="/useredit/{userid}",method=RequestMethod.GET)
- 限定POST方法
- ```
@RequestMapping(method = RequestMethod.POST)
如果通过Post访问则报错:
HTTP Status 405 - Request method 'GET' not supported
@RequestMapping(value="/useredit/{userid}",method=RequestMethod.POST)
GET和POST都可以
- ```
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
4.4 请求数据绑定
Controller方法通过形参接收页面传递的参数。
@RequestMapping("/userlist")
public String userlist(HttpServletRequest request,
HttpServletResponse response,
HttpSession session,
Model model
){
}
- 默认支持的参数类型
- - HttpServletRequest:通过request对象获取请求信息
- - HttpServletResponse:通过response处理响应信息
- - HttpSession:通过session对象得到session中存放的对象
- - Model:通过model向页面传递数据
- - ```
model.addAttribute("user", new User("李四"));
页面通过${user.XXXX}获取user对象的属性值。
- 命令/表单对象:自动将请求参数绑定到功能处理方法的命令/表单对象上,Controller方法通过形参接收命令/表单对象。
- Java基本数据类型
- 布尔型:
<tr>
<td>用户状态:</td>
<td>
<inputtype="radio"name="userstate"value="true"/>
<inputtype="radio"name="userstate"value="false"/></td>
</tr>
<tr>
- - - 整型
- - - ```
<tr>
<td>用户状态:</td>
<td>
<inputtype="radio"name="userstate"value="1"/>
<inputtype="radio"name="userstate"value="2"/></td>
</tr>
<tr>
- 单精度/双精度
<tr>
<td>用户状态:</td>
<td>
<inputtype="radio"name="userstate"value="1.2"/>
<inputtype="radio"name="userstate"value="1.22"/></td>
</tr>
<tr>
- - - 日期型需要添加属性编辑器:
- - - ```
@InitBinder
public void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
- Pojo对象
页面上以pojo对象名点属性名命名:
如果采用类似struts中对象.属性的方式命名,需要将pojo对象作为一个包装对象的属性,action中以该包装对象作为形参。
包装对象定义如下:
- - ```
public class UserVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
页面定义:
<input type="text" name="user.age" />
<input type="text" name="user.birthday" />
Controller方法定义如下:
- - ```
public String useraddsubmit(Model model,UserVo userVo)throws Exception{
System.out.println(userVo.getUser());
}
- 字符串数组
页面定义如下:
页面选中多个checkbox向controller方法传递
- 字符串数组
<input type="checkbox" name="deleteid" value="001"/>
<input type="checkbox" name="deleteid" value="002"/>
<input type="checkbox" name="deleteid" value="002"/>
传递到controller方法中的格式是:001,002,003
Controller方法中可以用String[]接收,定义如下:
- - ```
public String deletelist(String[] deleteid)throws Exception{
System.out.println(deleteid);
}
- List
List中存放对象,并将定义的List放在包装类中,action使用包装对象接收。
List中对象:
- List
//成绩对象
public class StudentScore {
private String coursename;//课程名称
private Float score;//成绩
public String getCoursename() {
returncoursename;
}
public void setCoursename(String coursename) {
this.coursename = coursename;
}
public Float getScore() {
returnscore;
}
public void setScore(Float score) {
this.score = score;
}
}
包装类中定义List对象,并添加get/set方法如下:
- - ```
public class UserVo {
private List<StudentScore> scores;//成绩
//get/set方法..
}
页面:
<tr>
<td>课程成绩:</td>
<td>
课程名:<input type="text"name="scores[0].coursename"/>成绩:<input type="text"name="scores[0].score"/>
课程名:<input type="text"name="scores[1].coursename"/>成绩:<input type="text"name="scores[1].score"/>
课程名:<input type="text"name="scores[2].coursename"/>成绩:<input type="text"name="scores[2].score"/>
</td>
</tr>
Contrller方法定义如下:
- - ```
public String useraddsubmit(Model model,UserVo userVo)throws Exception{
System.out.println(userVo.getScores ());
}
- @RequestParam绑定单个请求参数
value:参数名字,即入参的请求参数名字,如value=“studentid”表示请求的参数区中的名字为studentid的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值
public String userlist(@RequestParam(defaultValue="2",value="group",required=true) String groupid) {
}
形参名称为groupid,但是这里使用value="group"限定参数名为group,所以页面传递参数的名必须为group。
这里通过required=true限定groupid参数为必需传递,如果不传递则报400错误,由于使用了defaultvalue=”2”默认值即使不传group参数它的值为”2”,所以页面不传递group也不会报错,如果去掉defaultvalue=”2”且定义required=true则如果页面不传递group则会报错。
- @PathVariable 绑定URI 模板变量值
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上
- ```
@RequestMapping(value="/useredit/{groupid}/{userid}",method={RequestMethod.GET,RequestMethod.POST})
public String useredit(@PathVariable String groupid,@PathVariable String userid,Model model) throws Exception{
//方法中使用@PathVariable获取useried的值,使用model传回页面
model.addAttribute("groupid", groupid);
model.addAttribute("userid", userid);
return"/user/useredit";
}
如请求的URL 为“控制器URL/useredit/1/admin.action”,则自动将URL 中模板变量{groupid}和{userid}绑定到@PathVariable注解的同名参数上,即入参后groupid=“1”、userid=“admin”