文章摘要
一、Spring MVC 入门
简化Web应用程序的开发。 Spring MVC 是Spring体系的轻量级Web MVC框架。简化了传统的J2EE里的Servlet。Spring MVC的核心是Controller
控制器,用于处理请求、产生相应。Spring MVC基于Spring IoC容器运行,所有对象被IoC管理。
1.1、Spring MVC环境配置
前提是搭建好Maven WebApp、TomCat等环境。
1、Maven依赖注入spring-webmvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
2、web.xml配置DispatcherServlet
<!-- DispatchServlet 是Spring MVC的核心类。起作用是对所有请求进行拦截,
并根据请求的URL调用与之对应的Controller方法,来完成Http请求的处理。类似于一个公司的前台、生活中的邮局-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 初始化参数,来告诉DispatchServlet,在IOC 容器启动时,加载哪个 applicationContext.xml 文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!-- 在Web应用启动时自动创建Spring IOC 容器,并初始化DispatchServlet-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- "/"代表从根路径拦截 所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
3、配置applicationContex的mvc标记
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mv="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">
<!-- =========================Spring MVC 的配置=======================-->
<!-- 组件扫描器-->
<context:component-scan base-package="com.test.springmvc"></context:component-scan>
<!-- 启用Spring MVC 的注解开发模式-->
<mvc:annotation-driven/>
<!-- 将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
<mvc:default-servlet-handler/>
<!-- =================================================================-->
</beans>
4、开发Controller控制器
@Controller
public class TestController {
/**
* 处理请求
* @return 返回字符串
*/
@GetMapping("/t") //localhost/t
@ResponseBody//直接向响应提供数据,不进行页面跳转
public String test(){
return "SUCCESS!!";
}
}
二、URL Mapping (数据绑定)
Spring MVC数据绑定 ===>>> 就是URL 和 某一个Controller的方法绑定。例如一开始测试类中的:@GetMapping("/t") 注解
。这样Spring MVC可已通过TomCat对外暴露服务
注解 | 说明 |
---|---|
@RequestMapping | 通用绑定 |
@GetMapping | 绑定Get请求 |
@PostMapping | 绑定Post请求 |
三、接收 Web数据
3.1、接收单个请求参数
1、
使用Controller方法参数接收。
<form action="/p" method="post">
<input name="username" >
<input name="password" >
</form>
@PostMapping("/p")
@ResponseBody
public String post(String username,Long password){
return username + ":" + password;
}
2、
使用Java Bean接收数据
,直接把数据装到对象中。
设计实体类,其属性和请求数据的字段要一致。然后,在Controller类的方法中把参数设置成实体类型。
@PostMapping("/p1")
@ResponseBody
public String postMapping1(User user){
System.out.println(user);
return "This is post method";
}
3.2、接收表单复合数据
1、**利用数组或者List接收请求中的符合数据。
数组方式:
@Controller
@PostMapping("/apply")
@ResponseBody
public String apply(String name,String course,Integer[] purpose){
System.out.println(name);
System.out.println(course);
for (Integer p : purpose){
System.out.println(p);
}
return "SUCCESS";
}
利用@RequestParam为参数设置默认值。List方式:
@PostMapping("/apply")
@ResponseBody //@RequestParam告诉Spring把复合数据转化成list来接收
public String apply(String name, String course, @RequestParam List<Integer> purpose){
System.out.println(name);
System.out.println(course);
for (Integer p : purpose){
System.out.println(p);
}
return "SUCCESS";
}
还可以用==> 对象来接收,其中对象里面可以安置List集合:
public class From {
private String name;
private String course;
private List<Integer> purpose;
······
······
······
}
====================================
@PostMapping("/apply")
@ResponseBody
public String apply(From from){
return "SUCCESS";
}
2、使用Map对象接收请求参数的注意事项。
@PostMapping("/apply")
@ResponseBody //@RequestParam告诉Spring把数据转化成Map对象 来接收
public String apply(@RequestParam Map map){
return "SUCCESS";
}
上述方法出现 符合数据 丢失的问题。如果接收的数据没有符合数据,是可以用Map来接收的。
3.3、关联对象赋值
一个对象中引用了另一个对象。也就是这个被引用的对象 赋值操作就是 ==> 关联对象赋值
<h3>收货人</h3>
<input name="name" class="test" style="width: 150px">
<h3>联系电话</h3>
<input name="mobile" class="test" style="width: 150px;">
<h3>收货地址</h3>
<input name="address" class="test" style="width: 150px">
把上的数据 放到From类对象 的 Delivery引用类型属性里面去。
注:要把原始的表单字段名。改成 delivery.什么什么
=============================================
<h3>收货人</h3>
<input name="delivery.name" class="test" style="width: 150px">
<h3>联系电话</h3>
<input name="delivery.mobile" class="test" style="width: 150px;">
<h3>收货地址</h3>
<input name="delivery.address" class="test" style="width: 150px">
public class From {
private String name;
private String course;
private List<Integer> purpose;
引用对象 这里必须创建引用对象
private Delivery delivery = new Delivery();
······
······
······
}
==========================================
@PostMapping("/apply")
@ResponseBody
public String apply(From fromp){
System.out.println(from.getDelivery().getName());
return "SUCCESS";
}
3.4、接收日期类型的数据
接收前台发过来的一个日期字符串的请求。
1.用 注解 直接在参数 中添加
@DateTimeFormat(pattern ="yyyy-MM-dd" )
Date 参数名
@PostMapping("/p1")
@ResponseBody
public String postMapping1(User user, @DateTimeFormat(pattern ="yyyy-MM-dd" ) Date createTime){
System.out.println(user);
return "This is post method";
}
2.在实体类中添加 Date引用类型,
并在该类型上添加注解
@DateTimeFormat(pattern ="yyyy-MM-dd" )
public class User {
private String username;
private Long password;
@DateTimeFormat(pattern ="yyyy-MM-dd" )
private Date createTime;
······
······
······
}
上面的两种方案中,无论是在控制器方法参数中,还是在实体类,引入Date数据类型。都要加注解,如果嫌麻烦以下时解决方案:
1、做个转换器。可以看出这里做的是一个日期转换类
public class MyDateConverter implements Converter<String , Date> {
@Override
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(s);
return date;
} catch (ParseException e) {
return null;
}
}
}
2、以上转换器,SpringMVC 是不知道的。需要配置文件中写一下
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.test.springmvc.converter.MyDateConverter"></bean>
</set>
</property>
</bean>
然后把上面这个Bean的Id放到下面的注解
<!-- 启用Spring MVC 的注解开发模式-->
<mvc:annotation-driven conversion-service="conversionService"/>
四、中文乱码问题
问题产生的原因: TomCat默认的字符集是西欧字符集。
解决方法: 将默认字符集改成 ==> UTF-8。Controller中请求与响应都需要设置UTF-8。
Get请求乱码
TomCat 里的 server.xml文件 添加 URIEncoding属性
Post请求乱码
web.xml 配置 CharacterEncodingFilter
<!-- 配置过滤器-->
<filter>
<filter-name>characterFilter</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>characterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Response响应乱码
applicationContext.xml 配置StringHttpMessageConverter
<!-- 启用Spring MVC 的注解开发模式-->
<mvc:annotation-driven conversion-service="conversionService"/>
======================改成以下============================
<!-- 启用Spring MVC 的注解开发模式-->
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
五、响应输出
响应中产生的结果:
1、
@ResponseBody
==> 直接产生响应文本
@ResponseBody,直接产生响应体的数据,不涉及任何试图。可产生 标准字符串/JSON/XML 等数据格式。
@PostMapping("/p1")
@ResponseBody
public String postMapping1(User user){
System.out.println(user);
return "This is post method";
}
2、
ModelANdView
==> 动态渲染产生页面信息
ModelAndView对象是指: “数据 与 试图 ” 对象。ModelAndView 可将包含数据对象与模板引擎进行绑定。SpringMVC中默认的 View 是 JSP,也可以配置其他模板引擎。
@GetMapping("/view")
public ModelAndView showView(Integer userId){
ModelAndView mav = new ModelAndView("/view.jsp");
User user = new User();
if (userId ==1){
user.setUsername("小明");
}else if (userId == 2){
user.setUsername("小红");
}
// 数据和试图绑定
mav.addObject("u",user);
return mav;
}
上面的方法 常用的形式是:
// Controller方法返回String
// 1、方法被@ResponseBody 描述,Spring MVC直接影响 Sting 字符串本身
// 2、方法不存在@ResponseBody ,则Spring MVC 处理Sting 指代的页面
public String showView02(Integer userId, ModelMap modelMap){
String view = "/view.jsp";
User user = new User();
if (userId ==1){
user.setUsername("小明");
}else if (userId == 2){
user.setUsername("小红");
}
// 数据和试图绑定
modelMap.addAttribute("u",user);
return view;
}
六、Spring MVC 与 Freemarker模板引擎
因为 SpringMVC中默认的 View 是 JSP,可以配置其他模板引擎。所以使用 Freemarker模板引擎。
1、pom.xml引入依赖
<!-- Freemarker 依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!-- spring上下文的支持包,对Freemarker整合以及支持类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
2、通知Spring MVC 使用Freemarker模板引擎(在applicationContext.xml中)
<!-- Freemarker-->
<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!-- 设置响应输出,并解决中文乱码-->
<property name="contentType" value="text/html;charset=utf-8"></property>
<!-- 指定Freemarker模板文件扩展名-->
<property name="suffix" value=".ftl"/>
</bean>
3、对Freemarker本身进行参数设置(在applicationContext.xml中)
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 设置模板保存的目录-->
<property name="templateLoaderPath" value="/WEB-INF/ftl"></property>
<!-- 其他模板引擎设置-->
<property name="freemarkerSettings">
<props>
<!-- 设置Freemarker脚本与数据渲染时使用的字符集-->
<prop key="defaultEncoding">UTF-8</prop>
</props>
</property>
</bean>
@Controller
@RequestMapping("/fm")
public class FreemarkerController {
@GetMapping("/test")
public ModelAndView showTest(){ 此处不用再 .ftl 了。配置文件中配置好了,而且还要存放目录也配置好了。
ModelAndView mav = new ModelAndView("/test");
User user = new User(); 此处的/test.ftl文件应该再 ==> /WEB-INF/ftl目录下
user.setUsername("安迪");
mav.addObject("u",user);
return mav;
}
}