如果对Spring MVC还不了解,不妨先看看Spring MVC 初识,因为在注解版中,有些已经不再写了,但如果想理解实现原理,又不得不先繁再简。
在Spring MVC中,需要我们写Java代码的地方是Controller部分。之前学了注解,我们下面就利用注解的当时,将原来复杂的Model改简化吧!
1. 前期回顾
回看下当时的整个Model流程。
1️⃣ Step1:配置Web、Tomcat
2️⃣ Step2:在web.xml
中配置DispatcherServlet
3️⃣ Step3:在web.xml
中配置Spring MVC的配置文件
4️⃣ Step4:在web.xml
配置中启动级别(非必须)
5️⃣ Step5:在web.xml
中匹配到JSP
6️⃣ Step6:在Spring MVC配置文件中配置处理映射器
7️⃣ Step7:在Spring MVC配置文件中配置处理器适配器
8️⃣ Step8:在Spring MVC配置文件中配置视图解析器
9️⃣ Step9:在Controller中实现具体的业务
🔟 Step10:在Spring MVC配置文件中注册Controller
1️⃣1️⃣ Step11:JSP页面+测试
🌟 在注解版中,与原来不同的步骤分别是:6、7、9、10。
2. Spring MVC 配置文件
这是我们就省去了步骤6和步骤7,后面10能省掉。
在Spring MVC 配置文件留下配置视图解析器的部分。
由于我们将使用到注解,需要配置自动扫描、MVC注解驱动。
<mvc:default-servlet-handler/>
意为不处理静态资源。
<!--配置自动扫描-->
<context:component-scan base-package="Controller"/>
<!--不处理静态资源-->
<mvc:default-servlet-handler/>
<!--添加MVC注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
3. Controller
在Controller中不再需要new对象,一切通过注解搞定!
3.1 Controller注解
@Controller
:标识一个Spring类是Spring MVC controller处理器,是@Component的衍生注解。
@Component
衍生注解:@Controller
、@Service
、@Repository
3.2 两种Controller
Spring中有Controller、RestController的两种控制器,都是用来表示Spring某个类的是否可以接收HTTP请求。
- Controller:标识一个Spring类是Spring MVC controller处理器。
- RestController: 主要用于Restfull接口,返回客户端数据请求。
RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。
4. RequestMapping
在基于注解的控制器类中可以为每个请求编写对应的处理方法。
4.1 RequestMapping注解
@RequestMapping
:作用于类、接口、方法,用来处理请求地址映射。
annotaion包中的注解如下:
🌈 关注:@RequestParam、@GetMapping
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {...}
4.2 RequestMapping属性
public @interface RequestMapping {
String name() default "";
String[] value() default {};
String[] path() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
RequestMethod[] method() default {};
}
value:指定请求的实际地址,指定的地址可以是URI Template 模式
params: 映射请求的参数,缩小主映射。
headers: 映射请求的头,缩小主映射。
consumes: 控件可以使用的媒体类型来缩小主映射映射处理程序,如consumes = "text/plain
。
produces: 控件可以生成的媒体类型来缩小主映射映射处理程序,如produces = MediaType.TEXT_PLAIN_VALUE
。
method: 要映射到的HTTP请求方法,GET、POST、PUT、DELETE等;
4.3 ResquestMapping应用
@RequestMapping("/test")
public String test(...) {
return "test";
}
如上,在方法上使用@ResquestMapping
,其中的参数为映射的请求路径。
返回值为视图名(全路径:前缀+视图名+后缀)。
5. 编写Controller
@Controller
public class HelloController2 {
@RequestMapping("/Test")
public String test(Model model) {
model.addAttribute("username", "注解版Controller");
return "test";
}
}
以注解实现的Controller类中,Model类型的参数是为了把Action中的数据带到视图中。
RequestMapping("/Test")
:映射后的请求路径,即将teat映射为了Test
之前用的是ModelAndView,先在只需Model。
⚠️ 注意:通过RequestMapping传入映射路径,就不需要再Spring MVC 配置文件中注册Controller的Beanl,效果是一样的。
6. JSP + 测试
注意我们定义的URL前缀,我们再web路径下的jsp包中新建test.xml
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${username}
</body>
</html>
通过EL表达式获取定义的Attribute,类似于session.setAttribute
中的key-value。
测试,在地址栏中输入映射后的/Test
,结果如下:
7.写在最后
注解的使用,简化了代码量,但不易于理解底层的原理。
注意几点:
- 如果ResquestMapping里跟的了映射后路径名,就不需要再配置文件注册该Controller了,因为这就是Bean里的那个id。
- 方法中使用的是View,不再是ModelAndView。
- addAttribute方法实现的相当于之前的一个session,作用是用来传输数据。