Spring MVC入门与数据绑定

2022-10-31 14:57:13 浏览数 (1)

Spring MVC

  • Spring MVC是Spring体系的轻量级Web MVC框架
  • Spring MVC的核心Controller控制器,用于处理请求,产生响应
  • Spring MVC基于Spring IOC容器运行,所有对象被IOC管理

环境配置

  1. Maven依赖:spring-webmvc
  2. web.xml配置DispatcherServlet
  3. 配置applicationContext的mvc标记
  4. 开发Controller控制器
代码语言:javascript复制
<!--引入Spring MVC-->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.22</version>
    </dependency>
</dependencies>
代码语言:javascript复制
<!--DispatchServlet:对所有请求进行拦截-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <!--
            DispatcherServlet是Spring MVC最核心的对象
            DispatcherServlet用于拦截Http请求,
            并根据请求的URL调用与之对应Controller方法,来完成Http请求的处理
        -->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--applicationContext.xml-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </init-param>
    <!--在Web应用启动时自动创建Spring IOC容器,并初始化DispatcherServlet-->
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--“/”拦截所有请求-->
    <url-pattern>/</url-pattern>
</servlet-mapping>
代码语言:javascript复制
<?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">
    <!--
    context:component-scan 标签作用
    在Spring IOC初始化过程中,自动创建并管理com.hua.springmvc及子包中
    拥有以下注解的对象.
    @Repository     语义注解,说明当前类用于业务持久层,通长描述对应的Dao类
    @Service        语义注解,说明当前类是Service业务服务类
    @Controller     语义注解,说明当前类是MVC应用中的控制器类
    @Component      组件注解,通常注解,被该注解描述的类将被IoC容器管理并实现
    -->
    <context:component-scan base-package="com.hua.springmvc"/>
    <!--启用Spring MVC注解开发模式-->
    <mvc:annotation-driven/>
    <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
    <mvc:default-servlet-handler/>
</beans>

注解

用途

@GetMapping

将当前方法绑定某个Get请求方式的URL

@ResponseBody

直接向响应输出字符串数据,不跳转页面

数据绑定

URL Mapping

  • 将URL与Controller方法绑定
  • 同过URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务

注解

  1. @RequestMapping - 通用绑定
  2. @GetMapping - 绑定Get请求
  3. @PostMapping - 绑定Post请求

接受请求参数

代码语言:javascript复制
@Controller
@RequestMapping("/um") //定义类下所有方法的访问前缀
public class URLMappingController {

    @GetMapping("/g")
    //用用在方法上,不再区分Get/Post请求
    //@RequestMapping(value = "/g", method = RequestMethod.GET)
    @ResponseBody
    //@RequestParam 专用于特殊描述的参数,要书写在参数之前。同时增加映射原始请求参数
    public String getMapping(@RequestParam("manager_name")String managerName) {
        System.out.println("manager_name:"   managerName);
        return "This is Get method";
    }

    @PostMapping("/p")
    @ResponseBody
    public String postMapping(String username, String password) {
        System.out.println(username   ":"   password);
        return "This is Post method";
    }

    @PostMapping("/p1")
    @ResponseBody
    public String PostMapping1(User user) {
        System.out.println(user.getUsername()   ":"   user.getPassword());
        return "This is Post method";
    }
}

接收表单复合数据

  • 如果要接受复合数据可以使用数组、LIst和Map接收,List集合接收数据是需要添加@RequestParam声明,Map接受符合数据会出现数据丢失的情况
代码语言:javascript复制
@Controller
public class FormController {

//    @PostMapping("/apply")
    @ResponseBody
    // 当值参数名n不存在的时候返回默认值ANON
    public String Apply(@RequestParam(value = "n",defaultValue = "ANON") String name, String course, Integer[] purpose) {
        System.out.println(name);
        System.out.println(course);
        for (Integer p : purpose) {
            System.out.println(p);
        }
        return "success";
    }

//    @PostMapping("/apply")
    @ResponseBody
    // 使用List接收符合数据需要在参数前添加 @RequestParam 声明
    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";
    }

//    @PostMapping("/apply")
    @ResponseBody
    public String Apply(Form form) {
        return "success";
    }

    @PostMapping("/apply")
    @ResponseBody
    //使用Map接受复合数据会出现数据丢失
    public String Apply(@RequestParam Map map) {
        return "success";
    }
}

关联对象赋值

在参数名称前加上对象

日期类型转换

@DateTimeFormat注解

用于表示日期转换与 SimpleDataFormat 相似

代码语言:javascript复制
public String postMapping(String username, String password,@DateTimeFormat(pattern = "yyyy-MM-dd") Date createtime) {
    System.out.println(username   ":"   password);
    return "This is Post method";
}
实体类转换日期

这里也需要添加 @DateTimeFormat

代码语言:javascript复制
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createtime;
设置全局日期转换类

继承Converter接口,设置泛型<传入参数(K), 转换后的参数(V)>

代码语言:javascript复制
public class MyDateConverter implements Converter<String, Date> {
    public Date convert(String s) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date d = sdf.parse(s);
            return d;
        } catch (ParseException e) {
            return null;
        }
    }
}
代码语言:javascript复制
<!--在这里额外添加属性 conversion-service="conversionService"-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 将前台传进的日期进行转换 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.hua.springmvc.converter.MyDateConverter"/>
        </set>
    </property>
</bean>
优先级问题

通常有全局转换器存在会优先选择转换器进行日期转换,没有转换器使用注解转换

中文乱码

  • Get请求乱码 - server.xml增加URIEncoding属性
  • Post请求乱码 - web.xml配置CharacterEncodingFilter
  • Response响应乱码 - Spring配置StringHttpMessageConverter
Get请求乱码

打开 Tomcat/conf/server.xml 添加 URIEncoding="UTF-8"

Post请求乱码
代码语言:javascript复制
<!--过滤器-->
<filter>
    <filter-name>characterFilter</filter-name>
    <!--将Post请求中的ISO-8859-1转换为UTF-8-->
    <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响应乱码
代码语言:javascript复制
<mvc:annotation-driven conversion-service="conversionService">
    <!--设置消息转换器-->
    <mvc:message-converters>
        <!--进行文本消息转换-->
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <!--支持的媒体类型-->
            <property name="supportedMediaTypes">
                <list>
                    <!--response.setContentType("text/html;charset=utf-8")-->
                    <value>text/html;charset=utf-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

响应输出结果

  • @ResponseBody - 产生响应文本
  • ModelAndView - 利用模板引擎渲染输出
@ResponseBody
  1. 直接产生响应体的数据,过程不干涉任何视图
  2. 可产生标准的字符串/JSON/XML等格式数据
  3. 产生的字符串被StringHttpMessageConverter影响
ModelAndView

指"模型(数据)"与"视图(界面)"对象 通过ModelAndView可将包含数据对象与引擎进行绑定 SpringMVC中默认的View是JSP,也可以配置其他模板引擎

代码语言:javascript复制
@GetMapping("/view")
public ModelAndView showView() {
    ModelAndView mav = new ModelAndView();
    return mav;
}
  • mav.addObject()方法设置的属性默认存放在当前请求中
  • 默认ModelAndView使用请求转发(forward)至页面
  • 重定向使用new ModelAndView("redirect:/index.jsp")
String与ModelMap实现类似功能
代码语言:javascript复制
//String与ModelMap
//Controller方法返回String的情况
//1. 方法被@ResponseBody描述,SpringMVC直接响应String字符串本身
//2. 方法不存在@ResponseBody,则SpringMVC处理String指代的视图(页面)
@GetMapping("/xxxx")
//    @ResponseBody
public String showView1(Integer userId , ModelMap modelMap){
    String view = "/um/view.jsp";
    User user = new User();
    if(userId == 1){
        user.setUsername("lily");
    }else if(userId == 2){
        user.setUsername("smith");
    }else if(userId == 3){
        user.setUsername("lina");
    }
    modelMap.addAttribute("u", user);
    return view;
}

SpringMVC整合Freemarker

1-引入依赖

代码语言:javascript复制
<dependencies>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.28</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
</dependencies>

2-启用Freemarker模板引擎

代码语言:javascript复制
<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <!--设置响应体输出,解决响应体中文乱码问题-->
    <property name="contentType" value="text/html;charset=utf-8"/>
    <!--指定Freemarker模板文件扩展名-->
    <property name="suffix" value=".ftl"/>
</bean>

3-通知Freemarker文件在哪

代码语言:javascript复制
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <!--定义Freemarker存放地址-->
    <property name="templateLoaderPath" value="/WEB-INF/ftl"/>
    <!--模板在渲染过程中的中文乱码问题-->
    <property name="freemarkerSettings">
        <props><prop key="defaultEncoding">UTF-8</prop></props>
    </property>
</bean>

0 人点赞