Spring MVC入门及数据绑定

目录

一、Spring MVC是什么?

二、使用步骤

1.引入依赖

2.web.xml配置DispatcherServlet

3.配置applicationContext的mvc标记

4.开发Controller控制器

5.配置tomcat

三、SpringMVC数据绑定

1.URL Mapping(URL映射

2.Controller方法参数接受数据

1.带参的Controller方法接受数据

2.参数名不一致的Controller方法

3.Controller实体对象接受参数

4.URL绝对路径与相对路径

5.接收表单复合数据

1. 使用数组接收复合数据

2. 使用List集合接收复合数据

3.使用对象形式接收复合数据

4.使用Map接收复合数据

5.关联对象赋值

6.接收日期类型 

6.解决中文乱码

7.响应输出结果

@ResponseBody

ModelAndView对象

ModelAndView对象核心方法

8.SpringMVC整合Fremarker模板引擎

1. pom.xml引入依赖

2.启用Freemarker模板引擎

3.配置Freemarker参数

4.在tomcat加入依赖


一、Spring MVC是什么?

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

Spring MVC 使用 MVC 架构模式的思想,将 Web 应用进行职责解构,把一个复杂的 Web 应用划分成模型(Model)、控制器(Contorller)以及视图(View)三层,有效地简化了 Web 应用的开发,降低了出错风险,同时也方便了开发人员之间的分工配合。

 View:界面部分,与用户的交互,负责将请求的处理结果进行渲染,展示在客户端浏览器上。

Controller:是 Model 和 View 交互的纽带;主要负责接收用户请求,并调用 Model 对请求处理,然后将 Model 的处理结果传递给 View。

Model:业务逻辑部分,负责对请求进行处理,并将结果返回给 Controller。

Spring 5.x最低要求JDK8与J2EE 7(Servlet3.1 / Tomcat 8.5+ ),支持JDK8/9,支持响应式编程。

二、使用步骤

1.引入依赖

阿里云镜像仓库

 <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
</repositories>

 Maven依赖spring-webmvc

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.18</version>
        </dependency>

        <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>

        <!-- getmapping注解 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
</dependencies>

2.web.xml配置DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
        <!--DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>

        <!--DispatcherServlet是Spring MVC最核心对象-->
        <!--DispatcherServlet用于拦截Http请求-->
        <!--并根据请求的URL调用与之对应的Controller方法,来完成Http请求处理-->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>

        <!--在Web应用启动时自动创建Spring IOC容器,并初始化DispatcherServlet-->
        <!--如果没有写注释下面语句,会在第一次URL访问的时候创建-->
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--"/"代表拦截所有请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

3.配置applicationContext的mvc标记

 applicationContext.xml对spring进行配置:

 resources目录下的applicationContext.xml,文件名字必须与上面web.xml配置的<init-param>中的<param-value>的classpath命名一致。表头增加了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">

    <!--
    context:component-scan 标签作用
    在Spring IOC初始化过程中,自动创建并管理com.yygs.springmvc及子包中
    拥有以下注解的对象.
    @Repository
    @Service
    @Controller
    @Component
    -->
    <context:component-scan base-package="com.yygs.springmvc"></context:component-scan>

    <!--启用Spring MVC的注解开发模式-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>

4.开发Controller控制器

 测试类:

@Controller
public class TestController {
    @GetMapping("/t")
    @ResponseBody //直接向响应输出字符串数据,不跳转页面
    public String test(){
        return "SUCCESS";
    }
}

5.配置tomcat

eidt Configuration中,左上角选择Tomcat Server --> Local -->Deployment,添加web项目。修改访问的URL根地址。

SpringMVC处理示意图: 

三、SpringMVC数据绑定

1.URL Mapping(URL映射

URL Mapping指将URL与Controller方法绑定,同时通过方法绑定,SpringMVC可通过tomcat对外暴露服务。

@RequestMapping  -通用绑定

@GetMapping -绑定Get请求

@PostMapping -绑定Post请求

@Controller
@RequestMapping("/um") //更多用在类上
public class URLMappingController {

    @GetMapping("/g")
    //作用在方法上,不再区分get/post请求
    //@RequestMapping(value="/g",method = RequestMethod.GET)
    @ResponseBody
    public String getMapping(){
        return "This is get method";
    }

    //postMapping不能直接在导航栏访问,不然会出现405错误
    @PostMapping("/p")
    @ResponseBody
    public String postMapping(String username,Long password){
        return "This is post method";
    }
}

2.Controller方法参数接受数据

1.带参的Controller方法接受数据

index.html中的表单用于提交数据:

<body>
    <form action="/um/p1" method="post">
        <input name="username"><br/>
        <input name="password"><br/>
        <input name="createTime"><br/>
        <input type="submit" value="提交">
    </form>
</body>

Controller中接受表单填写的数据:

@PostMapping("/p")
    @ResponseBody
    public String postMapping(String username,Long password){
        //User u = new User()
        //u.setUsername(username)
        //request.getParameter()
        System.out.println(username+":"+password);
        return "This is post method";
}

这样就不需要像以前一样使用Request,getParameter(...)获取数据。

SpringMVC还会对参数的数据类型进行转换。如果不能进行类型转换,就会返回400错误。  控制台会有警告:Java.lang.NumberFormatException:......

2.参数名不一致的Controller方法

@RequestParam("manager_name")String managerName :manager_name 为参数原始名字。

 @GetMapping("/g")
    //作用在方法上,不再区分get/post请求
    //@RequestMapping(value="/g",method = RequestMethod.GET)
    @ResponseBody
    public String getMapping(@RequestParam("manager_name") String managerName , Date createTime){
        System.out.println("managerName:"+managerName);
        return "This is get method";
}

3.Controller实体对象接受参数

如果前台传入的数据过多的话,使用Controller参数方法进行传输的话,会使得方法的参数填写十分繁琐,而且在传输实体类的时候还要在方法内重复set属性值。springMVC允许一次性传输实体类。

1.创建实体类:

entity下的User类

public class User {

    private String username;
    private Long password;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Long getPassword() {
        return password;
    }

    public void setPassword(Long password) {
        this.password = password;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

2:Controller类内的方法可直接传入实体类。要注意的是前端传入的数据的属性名要跟实体类属性名相同。

    @PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user){
        return "this is post method";
    }

//如果在方法的参数除了实体还有实体的某一属性参数,MVC会一并将其全部进行赋值,是同一实体数据。

    @PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user , String name){
        return "this is post method";
    }

4.URL绝对路径与相对路径

/开头的必然是绝对路径,就必须要 上下文。

 使用相对路径的应用案例,只需要保证提交地址apply与form.html同级,就能保证数据的送达。

5.接收表单复合数据

1. 使用数组接收复合数据

//    @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";
    }

如果提交者是匿名:name会产生一个空的对象,可以为其设置默认值。数据存在会将以ANON值存储。

//    @PostMapping("/apply")
    @ResponseBody
    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";
    }

2. 使用List集合接收复合数据

 必须在LIst参数前增加@RequestParam注解

//    @PostMapping("/apply")
    @ResponseBody
    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集合和数组差别不大,但是List集合提供了更多的控制方法处理数据。

3.使用对象形式接收复合数据

 创建实体类:

public class Form {
    private String name;
    private String course;
    private List<Integer> purpose;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public List<Integer> getPurpose() {
        return purpose;
    }

    public void setPurpose(List<Integer> purpose) {
        this.purpose = purpose;
    }
}

Controller类:

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

4.使用Map接收复合数据

 必须在参数前加@RequestParam注解。

    @PostMapping("/apply")
    @ResponseBody
    public String apply(@RequestParam Map map){
        System.out.println(map);
        return "SUCCESS";
    }

但是在数据中使用了复合数据,一定不要使用map。否则只返回一个数据,会产生丢失。

 只有第会返回第一个数据。即:工作要求。


 在日常使用中,有复合数据使用数组是最简单的。


5.关联对象赋值

 实体类设计:


在使用复杂的表单处理时,表单实体类又包含有别的实体类属性,那么可以通过表单关联对象的形式提交数据,为后台数据结构自动赋值例如:

页面: 

 页面代码:

<div class="container">
        <h2>学员调查问卷</h2>
        <form action="./apply" method="post">
        <h3>您的姓名</h3>
        <input name="name" class="text"  style="width: 150px">
        <h3>您正在学习的技术方向</h3>
        <select name="course" style="width: 150px">
            <option value="java">Java</option>
            <option value="h5">HTML5</option>
            <option value="python">Python</option>
            <option value="php">PHP</option>
        </select>
        <div>
            <h3>您的学习目的:</h3>
            <input type="checkbox" name="purpose" value="1">就业找工作
            <input type="checkbox" name="purpose" value="2">工作要求
            <input type="checkbox" name="purpose" value="3">兴趣爱好
            <input type="checkbox" name="purpose" value="4">其他
        </div>

         <h3>收货人</h3>
         <input name="delivery.name" class="text" style="width: 150px">
         <h3>联系电话</h3>
         <input name="delivery.mobile" class="text" style="width: 150px">
         <h3>收货地址</h3>   
         <input name="delivery.address" class="text" style="width: 150px">
            
        <div style="text-align: center;padding-top:10px" >
            <input type="submit" value="提交" style="width:100px">
        </div>
        </form>

</div>

Delivery实体类:

public class Delivery {
    private String name;
    private String address;
    private String mobile;

    public Delivery(String name, String address, String mobile) {
        this.name = name;
        this.address = address;
        this.mobile = mobile;
    }

    public Delivery() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}

外层实体类,还需要生成delivery的set、get方法。

public class Form {
    private String name;
    private String course;
    private List<Integer> purpose;
    private Delivery delivery = new Delivery();

    public Delivery getDelivery() {
        return delivery;
    }

    public void setDelivery(Delivery delivery) {
        this.delivery = delivery;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public List<Integer> getPurpose() {
        return purpose;
    }

    public void setPurpose(List<Integer> purpose) {
        this.purpose = purpose;
    }
}

Controller类:

//  @PostMapping("/apply")
    @ResponseBody
    public String applyDelivery(Form form){
        System.out.println(form.getDelivery().getName());
        return "SUCCESS";
    }
   

6.接收日期类型 

如果前端发送日期的字符串数据,后端用Date类型接收,会返回400错误,也就是数据转换错误。因此我们需要手动进行转换。在Date参数前增加@DateTimeFormat 注解,pattern参数写的时传入参数的格式。传入的数据会转换成日期对象。

@PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user , String username ,@DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime){
        System.out.println(user.getUsername() + ":" + user.getPassword());
        return "<h1>这是Post响应</h1>";
    }

在包含日期的表单中,使用实体类接收的时候需要增加对应的日期属性及其set、get方法,并且要在属性上增加@DateTimeFormat(pattern= "...")注解。

public class User {

    private String username;
    private Long password;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Long getPassword() {
        return password;
    }

    public void setPassword(Long password) {
        this.password = password;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

还可以设置全局默认时间格式,来避免重复的编写上面的注解代码。

创建springmvc.converter.MyDateConverter类,并实现Converter转换器接口:

//String原始字符串类型,Date为目标类型
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;
        }
    }
}

在applicationContext.xml注册该类:

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.yygs.springmvc.converter.MyDateConverter"/>
            </set>
        </property>
</bean>

在applicationContext.xml的<mvc:annotation-driven/>中增加属性:

<mvc:annotation-driven conversion-service="conversionService">

此时,直接使用Date类型接收前端发送的日期字符串数据就不会报错。

@PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user , String username , Date createTime){
        System.out.println(user.getUsername() + ":" + user.getPassword());
        return "<h1>这是Post响应</h1>";
}

如果在某时刻同时存在@DateTimeFormat注解,又使用了转换器,会优先使用转换器类处理数据。在转换器类中,可以通过if判断传入的数据的长度等进行不同的逻辑处理。

6.解决中文乱码

 web应用中文乱码的又来,根源是字符集。Tomcat默认使用IOS-8859-1,属于西欧字符集,包含英文、拉丁文字、数字、标准符号。但是不支持中文。

解决问题核心思路:将IOS-8859-1转换为UTF-8。

Controller请求与响应都需要设置UTF-8字符集才能保证中文的输出

Get请求乱码:server.xml增加URIEncoding属性

Post请求乱码:web.xml配置CharacterEncodingFilter

Response响应乱码:Spring配置SettingHttpMessageConverter


Get请求乱码:在tomcat目录的conf.server.xml中找到69行后面增加:URIEncoding="UTF-8"

tomcat8.0以上版本不需要设置,默认即为UTF-8,8.0之前必须增加!

Post请求乱码:在web.xml文件中增加过滤器<filter>以及<filter-mapping>应用到所有post请求。

<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文件中的<mvc:annotation-driven>中配置消息转换器<mvc:nessage-converters>

<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/plain;charset=utf-8</value>
                        <value>text/html;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
</mvc:annotation-driven>

7.响应输出结果

 响应中产生结果2种方法:

@ResponseBody -产生响应文本

ModelAndView -利用模板引擎渲染输出

@ResponseBody

1.直接产生响应体的数据,过程不涉及任何视图。

2.可产生标准字符串/json/xml等格式数据

3.被StringHttpMessageConverter所影响

ModelAndView对象

1.指“模型(数据)与试图(界面)”对象

2.通过ModelAndView可将数据对象与模板引擎进行绑定

3.SpringMVC中默认的View是JSP,也可以配置其他模板引擎

ModelAndView 的使用:(返回值是ModelAndView)

@GetMapping("/view")
    public ModelAndView showView(Integer userId){
    //根路径上的view.jsp
    ModelAndView mav = new ModelAndView("/view.jsp");
        
    return mav;
    }

此时我们注意,我们可以通过localhost/view可以访问,也可以直接通过localhost/view.jsp访问,

疑问:为何多此一举?

答:在Controller中有一些数据需要动态生成,然而jsp数据是静态的。此时我们需要先访问/view的Controller方法产生数据,之后再通过ModelAndView对象绑定到页面中展示出来

@GetMapping("/view")
    public ModelAndView showView(Integer userId){
        ModelAndView mav = new ModelAndView("/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");
        }

        mav.addObject("u" , user);
        return mav;
    }
<body>
    <h1>I'm view page</h1>
    <hr>
    <h3>Username:${u.username}</h3>
</body>

ModelAndView对象核心方法

1.mav.addObject(key,value) 方法设置的属性默认存放在当前的请求中

2.默认ModelAndeView使用请求转发(forward)至页面

3.重定向使用new ModelAndView("rediret:/index.jsp)

@GetMapping("/view")
    public ModelAndView showView(Integer userId){
        ModelAndView mav = new ModelAndView("/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");
        }
        mav.addObject("u" , user);
        return mav;
    }

访问localhost/view?userId=1的时候地址没有改变,那么请求是转发到view.jsp页面,jsp和controller共享一个request对象。

@GetMapping("/view")
    public ModelAndView showView(Integer userId){
        ModelAndView mav = new ModelAndView("redirect:/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");
        }
        mav.addObject("u" , user);
        return mav;
    }

当修改为页面重定向以后,访问地址会修改到localhost/view.jsp。因为服务端会通知客户端重新发起请求发送到/view.jsp。而原先的数据在重定向以后数据会丢失。

还可以进行如下编写:

@GetMapping("/view")
    public ModelAndView showView(Integer userId){
//        ModelAndView mav = new ModelAndView("redirect:/view.jsp");

        ModelAndView mav = new ModelAndView();
        mav.setViewName("/um/view.jsp"); //也有可能不带前缀"/",即相对路径,会根据类上的        
                                         //@RequestMapping所定义的前缀去找对应的页面。如果                        
                                         //带"/",那么就是直接找webapp/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");
        }
        mav.addObject("u" , user);
        return mav;
    }

使用String与ModelMap实现ModelAndView

Controller方法返回String的情况
    1. 方法被@ResponseBody描述,SpringMVC直接响应String字符串本身
    2. 方法不存在@ResponseBody,则SpringMVC处理String指代的视图(页面)

//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;
    }

8.SpringMVC整合Fremarker模板引擎

1. pom.xml引入依赖

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>

            <!--版本号必须与spring-webmvc的依赖一致-->
            <version>5.3.18</version>
        </dependency>

2.启用Freemarker模板引擎

 applicationContext.xml

启用引擎:

<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <!--输出内容的响应字符集-->
        <property name="contentType" value="text/html;charset=utf-8"/>
        <property name="suffix" value=".ftl"/>
</bean>

3.配置Freemarker参数

需在WEB-INF文件下创建ftl目录。

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <!--设置模板保存的目录-->
        <property name="templateLoaderPath" value="/WEB-INF/ftl"/>
        <!--其他模板引擎设置-->
        <property name="freemarkerSettings">
            <props>
                <!--设置Freemarker脚本与数据渲染时使用的字符集,而不是渲染完成后响应的字符集-->
                <prop key="defaultEncoding">UTF-8</prop>
            </props>
        </property>
</bean>

使用:controller.FreemarkerController类

@Controller
@RequestMapping("/fm")
public class FreemarkerController {
    @GetMapping("/t")
    public ModelAndView showTest(){
        // "/"代表根路径,根目录并不是webapp,而是WEB-INF下的ftl
        ModelAndView mav = new ModelAndView("/test");
        User user = new User();
        user.setUsername("andy");
        mav.addObject("u", user);
        return mav;
    }
}

4.在tomcat加入依赖

 Edit Configuration -->选择tomcat8.5.40  -->Deployment --> 左键选中项目

 Edit Artifact

 将右边的依赖全部选中,邮件点击Put into/WEB-INF/lib

 点击OK。这样底层依赖包就完整了。不然就出现找不到类的情况。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值