一、基本组成
Spring MVC 是 Spring 提供给 Web 应用的框架设计。Spring MVC 是一个典型的教科书式的 MVC构架,MVC即model应用层,view视图层,contoller控制层,三个组成部分,他们的功能分别是:
- 模型层:用于存储数据以及处理用户请求的业务逻辑。
- 视图层:向控制器提交数据,显示模型中的数据。
- 控制层:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。
使用IDEA创建一个SpringMVC项目,其基本结构如图所示:
二、模块实现
Spring MVC本质上相当于一个Servlet,从前台获取到的数据在传入到后端的时候,首先会在web.xml文件中被我们设置的DispatcherServlet拦截,通过识别,寻找到对应的Spring MVC配置文件,具体实现如下:
<servlet>
<!--起的别名,与下方名称一致-->
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置文件的路径,名称最好使用name-servlet.xml的格式,否则可能会出错-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC-servlet.xml</param-value>
</init-param>
</servlet>
<!--设置前端传入数据请求的范围,SpringMVC默认为*.do即后缀名为.do的请求,这里设置/表示拦截所有请求-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
我们也可以像Servlet一样设置拦截器,对传入和传出数据的编码格式进行设置,不同的是拦截器也需要设置在web.xml文件中。具体如下:
<!--过滤器,编码格式问题-->
<filter>
<filter-name>characterencoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!--/*表示拦截所有传入与传出的请求-->
<filter-mapping>
<filter-name>characterencoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在SpringMVC-servlet.xml配置文件中,因为需要应用注解,所以我们需要在文档中加入自动扫描上下文包,并使注解生效:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!--自动扫描上下文包-->
<context:component-scan base-package="cn.zc.*"></context:component-scan>
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler></mvc:default-servlet-handler>
同时需要在这个文档中设置视图解析器
<!--视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀加上的是jsp 页面的路径,/为根目录webapp,可根据自身页面的位置调整-->
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
通过bin注入对每个请求加上前缀(“prefix”)和后缀(“suffix”),以使程序可以识别页面响应的数据。
测试类书写在HelloController之中:
//表示以下为控制层的代码
@Controller
public class HelloController {
//前端通过访问hello.do即可访问控制层的方法
@RequestMapping("/hello.do")
public String hello(){
System.out.println("Hello");
//页面跳转至index.jsp,因为有视图解析器,.jsp需省略不写。
return "index";
}
}
在浏览器中输入http://localhost:8080/hello.do即可在控制台中输出“Hello”,并跳转至index.jsp页面
三、参数传递
1、视图层—>控制器
直接传入:
//前端传入name,有值则输出值,无值则输出null
@RequestMapping("/hello.do")
public String hello(String name){
System.out.println(name);
return "index";
}
使用注解传入:
//前端传入,有值输出值,无值不输出。
@RequestMapping("/hello.do")
public String hello(@RequestParam String name){
System.out.println(name);
return "index";
}
若前端传入的参数为非必需的,可通过设置required = false控制传来的参数是否为必需
// 对传过来参数是非必需的,有参输出,无参空白,required = false控制传来的参数是否为必需,
@RequestMapping("/hello.do")
public String hello(@RequestParam(value ="name",required = true) String name){
System.out.println(name);
return "index";
}
直接在映射注解中设置参数属性:
//前端传入,有值输出值,无值不输出。
@RequestMapping(value = "/hello.do",method = RequestMethod.GET,params = "name")
public String hello(String name){
System.out.println(name);
return "index";
}
以上几种需在浏览器的访问路径中输入
http://localhost:8080/hello.do?name=
加上想传入的参数来验证测试类
2、控制器—>视图层
以ModelAndView作为入参类型
//ModelAndView作为入参类型
@RequestMapping("/welcome.do")
public ModelAndView welcom(){
ModelAndView mv = new ModelAndView();
mv.addObject("name","zhang");//设置参数
mv.setViewName("index");//设置视图
return mv;
}
在index.jsp中通过${name}(传入参数的键名)获取传入的值。同理:
以Model作为入参类型
//以Model作为入参类型
@RequestMapping("/welcome.do")
public String welcome(Model model){
model.addAttribute("username","zhangzhang");//有键名则用键名获取值
model.addAttribute("noattr");//无键名则用数据类型输出
return "index";
}
使用Map作为入参类型
// 使用Map作为入参类型
@RequestMapping("/welcome.do")
public String welcome(Map<String,Object> map){
map.put("password","123456");
return "index";
}
综合小测试:
获取前端输入的用户名和密码,控制台输出,并将其发送给前端
前端index.jsp
<form action="/index" method="post">
用户名:<input name="username" type="text" id="name"><br>
密码:<input name="password" type="password" id="pwd"><br>
<input type="submit" value="提交">
</form>
控制器:
//数据回显
@RequestMapping("/index")
public ModelAndView success(String username,String password){
ModelAndView mv = new ModelAndView();
System.out.println(username+"---"+password);
mv.addObject("username",username);
mv.addObject("password",password);
mv.setViewName("success");
return mv;
}
成功跳转页面success.jsp:
<h3>用户${username}欢迎您的到来!!!!</h3>
结果如图: