Solo  当前访客:0 开始使用

Y 的个人博客

Java/C#/Linux

Spring Boot 快速入门之Web篇(二) 有更新!

2019-03-26 16:44:57 yang17762622
0  评论    90  浏览

一、前言

在前面的文章Spring Boot 快速入门之基础篇(一) 中简单的介绍的如何创建一个SpringBoot项目以及打包运行等基础知识。本篇文章继续深入了解SpringBoot与Web开发的相关知识。

二、模板引擎整合

由于 jsp 不被 SpringBoot 推荐使用,所以模板引擎主要介绍Freemarker和 Thymeleaf。

2.1 Freemarker 整合

FreeMarker说明文档 FreeMarker首页、文档和下载 - Java模板引擎 - 开源中国社区

2.1.1 添加Freemarker依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

2.1.2 添加Freemarker模板配置

在application.properties中添加配置(以下均为默认配置)

spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
spring.freemarker.prefix=
spring.freemarker.suffix=.ftl

2.1.3 Freemarker演示

在controller中创建FreemarkerController.java,内容如下:

@Controller

@RequestMapping("freemarker")

public class FreemarkerController {

    @RequestMapping("hello")
    public String hello(Map<String,String> map){
        map.put("message","Hello Freemarker");
        return "hello";
    }
}

在resource ->templates 中创建hello.html,重命名为hello.ftl,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Freemarker</title>
</head>
<body>
${message}
</body>
</html>

演示效果如下:

2.gif

2.2 Thymeleaf 整合

Thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发。它是一个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,该作者还是Java加密库Jasypt的作者。

Thymeleaf提供了一个用于整合Spring MVC的可选模块,在应用开发中,你可以使用Thymeleaf来完全代替JSP或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑

2.2.1 添加 Thymeleaf 依赖

        <dependency>

            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

2.2.2 添加Thymeleaf模板配置

#Thymeleaf 配置
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false

2.2.3 Thymeleaf演示

在controller中创建Thymeleaf.java,内容如下:

@Controller
@RequestMapping("thymeleaf")
public class Thymeleaf {
    
    @RequestMapping("hello")
    public String hello(Map<String,String> map){
        map.put("message","Hello Thymeleaf");
        return "hello";
    }
}

在resource ->templates 中创建hello.html,内容如下:

<!DOCTYPE html>

<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Thymeleaf</title>
</head>
<body>
<h2 th:text="${message}"></h2>
</body>
</html>

演示效果如下:

3.gif

三、自定义拦截器

3.1 创建interceptor包,在interceptor下创建拦截器TestInterceptor:

package com.y.springboot.springboot.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestInterceptor implements HandlerInterceptor {
    long start = System.currentTimeMillis();

    /**
     * 请求执行前执行的
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis();
        return true;
    }

    /**
     * 请求结束执行的
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }

    /**
     * 视图渲染完成后才执行
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

3.2 创建config包,在config下创建拦截器InterceptorConfig:

package com.y.springboot.springboot.config;

import com.y.springboot.springboot.interceptor.TestInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

public class InterceptorConfig extends WebMvcConfigurerAdapter  {

    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加拦截器和拦截url
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

目录结构如下:

image.png

演示效果:

4.gif

四、友好页面处理

先演示非友好页面,修改FreemarkerController中hello方法

@Controller

@RequestMapping("freemarker")
public class FreemarkerController {

    @RequestMapping("hello")
    public String hello(Map<String,String> map){
        map.put("message","Hello Freemarker");
        //模拟异常
        int result = 1/0;
        return "hello";
    }
}

访问 http://localhost:8080/freemarker/hello 异常页面如下:

image.png

当系统报错时,通常返回的都是一些杂乱的代码。这样对用户来说非常的不友好,所以我们要自定义一个友好的错误提示页面。

在resource下创建public/error/500.html

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>系统错误</title>
</head>
<body>
<h2>系统内部错误</h2>
</body>
</html>

处理完成后的页面

image.png

以上是处理500的错误信息,更多错误代码页面可以自行在public/error下创建对应的页面,进行处理。

五、整合Swagger2

5.1 添加Swagger2依赖

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>

5.2 添加测试类SwaggerCtroller:

package com.y.springboot.springboot.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@Api(description = "swagger测试controller")
@RequestMapping("swagger")
public class SwaggerController {

    @ApiOperation(value = "testSwaager测试方法" ,  notes="testSwaager测试方法")
    @ApiImplicitParam(name = "name", value = "用户名称", required = true, paramType = "query", dataType = "String")
    @RequestMapping(value = "/testSwaager",method = RequestMethod.GET)
    @ResponseBody
    public String testSwaager(@RequestParam("name") String name){
        return "hello "+ name +",欢迎测试swagger";
    }
}

注意上面的方法中有method = RequestMethod.GET,标识方法为get,如果使用 @RequestMapping 注解,不配置 method 属性swagger会生成7种请求方式哦。

启动项目,打开浏览器访问http://localhost:8080/swagger-ui.html。结果如下图:

image.png

六、文件上传和下载

6.1 添加commons-io依赖:

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

6.2 创建FileController类

package com.y.springboot.springboot.controller;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

@Controller
@Api(description = "文件上传下载")
@RequestMapping("file")
public class FileController {
    private String save_path = "F:\\";

    @ApiOperation(value = "上传文件",notes = "将上传文件存储至本地F盘")
    @RequestMapping(value = "uploadFile",method = RequestMethod.POST)
    @ResponseBody
    public String uploadFile(MultipartFile file){
        File localFile = new File(save_path, file.getOriginalFilename());
        try{
            file.transferTo(localFile);
        }catch (IOException ex){
            ex.printStackTrace();
            System.out.println("上传文件失败");
        }
        return localFile.getAbsolutePath();
    }

    @ApiOperation(value = "下载文件",notes = "根据文件路径下载文件")
    @ApiImplicitParam(name = "filePath", value = "文件路径", required = true, paramType = "query", dataType = "String")
    @RequestMapping(value="downloadFile",method = RequestMethod.GET)
    public void downloadFile(@RequestParam("filePath")String filePath, HttpServletResponse response){
        try {
            //输入
            InputStream inputStream = new FileInputStream(new File(filePath));
            //输出
            OutputStream outputStream = new FileOutputStream(new File(save_path,"download.png"));
            //设置ContentType类型
            response.setContentType("application/x-download");
            //文件名称
            response.addHeader("Content-Disposition", "attachment;filename=" + "download" + ".png");
            //copy
            IOUtils.copy(inputStream, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

6.2.1 文件上传

4.gif

6.2.2 文件下载

5.gif

emmmm,这个图的swagger注解filePath是因为复制的,所以显示的是"用户名称"。代码已经修改过来了,图就不更新了。

七、参考资料:

swagger2注解说明
ML-BLOG (读者可参考笔者的开源博客源码学习)

,

发表评论

TOP