这是一个servlet项目,功能是用户填写表单,然后后台渲染页面后把表单内容返回给用户。通过这个简单的例子理解下springmvc框架的工作原理。
springmvc概念架构
springmvc可以认为在传统MVC的模式上多了一个管理员DispatcherServlet
,管理员不干业务,只负责管理,用户给我请求,我就指派给具体的模块去处理
表单处理例子的架构
消息传递分析
用户发过来一个请求http://localhost:8080/HelloWeb/student
首先看web.xml
,这是一个servlet项目,首先会去web.xml
中查找配置:
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet首先有自己的mapping规则,这里我们把url-pattern=/
也就是所有的请求都转发给了HelloWeb
的servlet,这个servlet的处理器是DispatcherServlet
–也就是springmvc的管理员,load-on-startup=1
在tomcat启动时管理员就开始运行了。
然后看StudentCOntroller.jsp
,springmvc的mapping规则在这里面:
@Controller
public class StudentController {
@RequestMapping(value="/student", method=RequestMethod.GET)
public ModelAndView student() {
// 在名为 command 的ModelAndView中传递一个空的student
//因此spring框架需要一个名称为command的对象
// 当student()被调用时,返回一个student.jsp的试图
return new ModelAndView("student", "command", new Student());
}
@RequestMapping(value="/addStudent", method=RequestMethod.POST)
public String addStudent(@ModelAttribute("SpringWeb")Student student, ModelMap model) {
// 调用addStudent url中的post方法
//返回result.jsp试图
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("id", student.getId());
return "result";
}
}
@Controller
public class StudentController {
@RequestMapping(value="/student", method=RequestMethod.GET)
public ModelAndView student() {
// 在名为 command 的ModelAndView中传递一个空的student
//因此spring框架需要一个名称为command的对象
// 当student()被调用时,返回一个student.jsp的试图
return new ModelAndView("student", "command", new Student());
}
@RequestMapping(value="/addStudent", method=RequestMethod.POST)
public String addStudent(@ModelAttribute("SpringWeb")Student student, ModelMap model) {
// 调用addStudent url中的post方法
//返回result.jsp试图
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("id", student.getId());
return "result";
}
}
@RequestMapping(value="/student"
用户的请求http://localhost:8080/HelloWeb/student
发给了这个Handler,那么返回什么呢?返回return new ModelAndView("student", "command", new Student());
一个空的ModelAndView,在名称为 “command” 的 ModelAndView 对象中传递一个空的 Student 对象
这个ModelAndView会被DispatcherServlet交给student.jsp
这个具体的View去渲染,也就是把Model(这里是空Student对象)传递给了student.jsp
我们的student.jsp
主体长这个样子:
<form:form action="/HelloWeb/addStudent">
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td><form:label path="age">Age</form:label></td>
<td><form:input path="age" /></td>
</tr>
<tr>
<td><form:label path="id">Id</form:label></td>
<td><form:input path="id" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
</form:form>
<form:form action="/HelloWeb/addStudent">
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td><form:label path="age">Age</form:label></td>
<td><form:input path="age" /></td>
</tr>
<tr>
<td><form:label path="id">Id</form:label></td>
<td><form:input path="id" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
</form:form>
因为传递进来的是空值,也就是这个jsp原样展示给用户,用户最后看到:
下一步,用户填写信息name=zhangsan age=13 id=1234
表单通过post提交给http://localhost:8080/HelloWeb/addStudent
DispatcherServlet通过HandlerMapping,把post数据交给addStudent
这个控制器方法,然后控制器创造了一个ModelMap=model,并赋值
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("id", student.getId());
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("id", student.getId());
返回给result.jsp
result.jsp长这个样子:
<table>
<tr>
<td>Name</td>
<td>${name}</td>
</tr>
<tr>
<td>Age</td>
<td>${age}</td>
</tr>
<tr>
<td>Id</td>
<td>${id}</td>
</tr>
<table>
<tr>
<td>Name</td>
<td>${name}</td>
</tr>
<tr>
<td>Age</td>
<td>${age}</td>
</tr>
<tr>
<td>Id</td>
<td>${id}</td>
</tr>
这个的ModelMap是有数据的,分别渲染了上面对应的${name}这个字段,最后渲染好的jsp展示给用户:
总结下springmvc框架中,DispatcherServlet就是一个大指挥官,他规定的用户请求-响应的处理流程,通过这个指挥官把包含业务数据的模块与显示模块的视图解耦。简化日常Web开发。
对于实际编程来说,我的控制器不需要指导前端页面长什么样子,我只负责把需要的字段通过Map传递过去,springmvc自动帮我们渲染视图。
不得不赞一下注解功能,有了注解springmvc的的开发变得极为简单。
参考
https://www.w3cschool.cn/wkspring/v41f1mmk.html