spring boot ssm 案例 - wtdig/study GitHub Wiki

spring boot ssm 工程案例

一、案例详情

  1. pom文件

<properties>
        <project.build.sourceEncoding>UTF-8
        </project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>
    <dependencies>
        <!--spring boot start -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mybatis start -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.3</version>
        </dependency>
        <!--mybatis end -->
        <!--spring boot end -->
        <!--druid start -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.19</version>
        </dependency>
        <!--druid end -->
        <!--mysql start -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <!--mysql end -->
        <!--fast json start -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.14</version>
        </dependency>
        <!--fast json end -->
        <!--junit start -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <!--junit end -->
    </dependencies>
    <build>
        <!--spring boot plugin start -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--配置热部署 -->
                <dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.2.0.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
        <!--spring boot plugin end -->
    </build>
  1. resources文件

1)mapper文件夹下的mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.wt.springboot.mapper.SpringBootMapper">

    <select id="selectUserByName" resultType="User">
        select * from user where name = #{name}
    </select>

</mapper>

2)全局文件application.properties

#spring.datasource.url=jdbc:mysql://localhost:3306/springboot
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driverClassName=com.mysql.jdbc.Driver
#spring.jpa.database=mysql
#Mybatis扫描
#mybatis.mapper-locations=classpath*:mapper/*.xml
#起别名。可省略写mybatis的xml中的resultType的全路径
#mybatis.type-aliases-package=cn.wt.springboot.domain
# 驱动配置信息   
#spring.datasource.url = jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
#spring.datasource.username= root
#spring.datasource.password= root
#spring.datasource.driverClassName= com.mysql.jdbc.Driver
#spring.datasource.type= com.alibaba.druid.pool.DruidDataSource

3)数据源配置文件prop.properties

spring.datasource.url = jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
spring.datasource.username= root
spring.datasource.password= root
spring.datasource.driverClassName= com.mysql.jdbc.Driver
spring.datasource.type= com.alibaba.druid.pool.DruidDataSource

4)自定义banner文件banner.txt

           __      .___.__        
__  _  ___/  |_  __| _/|__| ____  
\ \/ \/ /\   __\/ __ | |  |/ ___\ 
 \     /  |  | / /_/ | |  / /_/  >
  \/\_/   |__| \____ | |__\___  / 
                    \/   /_____/  
  1. spring boot 入口文件

package cn.wt.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午2:27:04
 */
@SpringBootApplication
public class SsmSpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SsmSpringBootApplication.class, args);
    }
}

  1. spring boot 配置文件

1)数据源配置文件

package cn.wt.springboot.config;


import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.sql.SQLException;

/**
 * @author wb-wt261136
 */
@Configuration
@PropertySource("classpath:prop.properties")
public class DataSourcesConfig {

    /**
     * druid初始化
     * 
     * @return
     * @throws SQLException
     */
    @Value("${spring.datasource.url}")
    private String dbUrl;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;

    @Primary
    // 默认数据源
    @Bean(name = "dataSource", destroyMethod = "close")
    public DruidDataSource Construction() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(dbUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        // 配置最大连接
        dataSource.setMaxActive(20);
        // 配置初始连接
        dataSource.setInitialSize(1);
        // 配置最小连接
        dataSource.setMinIdle(1);
        // 连接等待超时时间
        dataSource.setMaxWait(60000);
        // 间隔多久进行检测,关闭空闲连接
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        // 一个连接最小生存时间
        dataSource.setMinEvictableIdleTimeMillis(300000);
        // 用来检测是否有效的sql
        dataSource.setValidationQuery("select 'x'");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        // 打开PSCache,并指定每个连接的PSCache大小
        dataSource.setPoolPreparedStatements(true);
        dataSource.setMaxOpenPreparedStatements(20);
        // 配置sql监控的filter
        dataSource.setFilters("stat,wall,log4j");
        try {
            dataSource.init();
        } catch (SQLException e) {
            throw new RuntimeException("druid datasource init fail");
        }
        return dataSource;
    }

}

2)mybatis配置文件

package cn.wt.springboot.config;


import com.github.pagehelper.PageHelper;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * mybatis配置类
 */
@Configuration
@EnableTransactionManagement
public class MybatisConfig implements TransactionManagementConfigurer {

    @Resource(name = "dataSource")
    private DataSource dataSource;

    /**
     * 可以通过这个类,详细配置mybatis
     * 
     * @return
     */
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean() {

        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage("cn.wt.springboot.domain");
        // 分页插件,插件无非是设置mybatis的拦截器
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("returnPageInfo", "check");
        properties.setProperty("params", "count=countSql");
        pageHelper.setProperties(properties);
        // 添加插件
        bean.setPlugins(new Interceptor[] { pageHelper });
        // 添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
            return bean.getObject();
        } catch (Exception e) {
            throw new RuntimeException("sqlSessionFactory init fail", e);
        }
    }

    /**
     * 用于实际查询的sql工具,传统dao开发形式可以使用这个,基于mapper代理则不需要注入
     * 
     * @param sqlSessionFactory
     * @return
     */
    @Bean(name = "sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 事务管理,具体使用在service层加入@Transactional注解
     */
    @Bean(name = "transactionManager")
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
}

3)消息json转换器配置文件

package cn.wt.springboot.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;

/**
 * 使用fastjson作为消息转换器
 */
@Configuration
public class WEBMessageConvert {

    /**
     * 使用bean注入,才能使其有效果,验证的话就在Entity字段中使用fastjson的 注解@JSONField(serialize = false),转换出来的信息不含该字段,则成功
     * 
     * @return
     */
    @Bean
    public HttpMessageConverters customConverters() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        return new HttpMessageConverters((HttpMessageConverter<?>) fastConverter);
    }
}

  1. spring boot 代码部分之controller

package cn.wt.springboot.controller;

import cn.wt.springboot.service.SpringBootService;
import cn.wt.springboot.domain.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午3:27:58
 */
@RestController
public class SpringBootController {

    @Autowired
    private SpringBootService springBootService;

    @RequestMapping("hello")
    public User queryByName() {
        User user = springBootService.queryByName("xh");
        System.out.println(user.toString());
        return user;
    }
}

  1. spring boot 代码部分之service

package cn.wt.springboot.service;

import cn.wt.springboot.domain.User;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午3:26:58
 */
public interface SpringBootService {

    public User queryByName(String name);
}

package cn.wt.springboot.service.impl;

import cn.wt.springboot.mapper.SpringBootMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wt.springboot.domain.User;
import cn.wt.springboot.service.SpringBootService;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午3:27:24
 */
@Service
public class SpringBootServiceImpl implements SpringBootService {

    @Autowired
    private SpringBootMapper springBootMapper;

    @Override
    public User queryByName(String name) {
        return springBootMapper.selectUserByName(name);
    }

}

  1. spring boot 代码部分之mapper

package cn.wt.springboot.mapper;

import org.springframework.stereotype.Repository;
import org.apache.ibatis.annotations.Mapper;
import cn.wt.springboot.domain.User;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午3:28:28
 */
@Mapper
@Repository
public interface SpringBootMapper {

    User selectUserByName(String name);
}

  1. spring boot 代码部分之domain

package cn.wt.springboot.domain;

import java.io.Serializable;

/**
 * @author wb-wt261136
 * @version 2017年10月16日 下午3:31:25
 */
public class User implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int               id;
    private String            name;
    private String            sex;
    private String            city;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", city=" + city + "]";
    }
}

二、spring boot各模块添加介绍

1. 添加全局异常处理

package cn.wt.springboot.exception;

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * spring boot的全局异常处理类
 * 
 * @author wb-wt261136
 * @version 2017年10月18日 上午10:10:04
 */
@ControllerAdvice
public class GlobalSpringBootException {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public String errorExceptionHandler(HttpServletRequest req, Exception e) {
        return "服务器繁忙!" + e.getMessage();
    }
}

2.使用自定义的fastjson

1)、在pom文件中添加依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.14</version>
</dependency>

2)、在spring boot启动类中继承WebMvcConfigurerAdapter,重写configureMessageConverters方法

/**
     * 启动类需要继承extends WebMvcConfigurerAdapter spring boot默认使用的是jackson,改为自定义的fastjson需要配置该bean
     * 
     * @return
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastConverter);
    }

3.spring boot集成测试的用法

1)、添加spring boot test依赖

 <!-- spring boot test依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2)、编写测试类

package cn.wt.springboot.test;

import org.springframework.boot.test.context.SpringBootTest;
import cn.wt.springboot.SsmSpringBootApplication;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.runner.RunWith;
import cn.wt.springboot.domain.User;
import cn.wt.springboot.service.SpringBootService;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;

/**
 * @author wb-wt261136
 * @version 2017年10月18日 下午3:54:32
 */
// SpringJUnit支持,由此引入Spring-Test框架支持!
@RunWith(SpringJUnit4ClassRunner.class)
// 指定我们SpringBoot工程的Application启动类
@SpringBootTest(classes = SsmSpringBootApplication.class)
public class MySpringBootTest {

    @Autowired
    private SpringBootService springBootService;

    @Test
    public void springTest() {
        User user = springBootService.queryByName("wt");
        System.out.println(user.toString());
    }
}

4.使用jsp模板引擎

1)、添加pom依赖

 <!-- jsp支持需要的依赖 start -->
        <!-- servlet依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- tomcat的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- jsp支持需要的依赖 end -->

2)、配置全局文件application.propreties

spring.mvc.view.prefix=/WEB-INF/jsp/

# \u54cd\u5e94\u9875\u9762\u9ed8\u8ba4\u540e\u7f00

spring.mvc.view.suffix=.jsp

# \u81ea\u5b9a\u4e49\u5c5e\u6027\uff0c\u53ef\u4ee5\u5728Controller\u4e2d\u8bfb\u53d6

application.hello=HelloAngel From application

3)、在WEB-INF下新建jsp文件夹,建立对应的xx.jsp文件helloJsp.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>hello</h1>
	<br />
	<span>${hello}</span>
	<hr />
	<h2>单文件上传</h2>
	<br/>
	<form action="/upload" enctype="multipart/form-data" method="post">
		文件:<input type="file" name="file">
		<br/>
		<input type="submit" value="上传">
	</form>
	<hr/>
	<h2>多文件上传</h2>
	<br/>
	<form method="POST" enctype="multipart/form-data"action="/batch/upload"> 
           <p>文件1:<input type="file"name="file" /></p>
           <p>文件2:<input type="file"name="file" /></p>
           <p>文件3:<input type="file"name="file" /></p>
           <p><input type="submit"value="上传" /></p>
     </form>
     <hr />
	<h2>指定位置文件上传</h2>
	<br/>
	<form action="/target/upload" enctype="multipart/form-data" method="post">
		文件:<input type="file" name="file">
		<br/>
		<input type="submit" value="上传">
	</form>
</body>
</html>

4)、编写contoller类

package cn.wt.springboot.controller;

import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;

/**
 * @author wb-wt261136
 * @version 2017年10月18日 下午2:32:46
 */
@Controller
public class SpringBootJspController {

    /**
     * 从 application.properties 中读取配置,如取不到默认值为HelloShanhy
     */
    @Value("${application.hello:Hello Angel}")
    private String hello;

    @RequestMapping("helloJsp")
    public String helloJsp(Map<String, Object> map) {
        System.out.println("HelloController.helloJsp().hello=" + hello);
        map.put("hello", hello);
        return "helloJsp";
    }
}

备注:返回值乱码解决方案:

 /**
     * 防止乱码 produces = "text/html;charset=UTF-8"
     */
    @RequestMapping(produces = "text/html;charset=UTF-8")

5.添加过滤器

1)、编写自定义过滤器

package cn.wt.springboot.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/**
 * @author wb-wt261136
 * @version 2017年10月18日 下午3:14:47
 */
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void destroy() {
        System.out.println("过滤器执行摧毁操作!");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
                                                                                             ServletException {
        System.out.println("过滤器执行过滤操作!");
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("过滤器执行初始化操作!");
    }

}

2)、在spring boot启动类上加上注解@ServletComponentScan

6.添加拦截器

1)、编写自定义拦截器

package cn.wt.springboot.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 拦截器
 * 
 * @author wb-wt261136
 * @version 2017年10月18日 下午3:24:20
 */
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                                                                                                               throws Exception {
        System.out.println(">>>MyInterceptor>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
                                                                                                             throws Exception {
        System.out.println(">>>MyInterceptor>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
    }

    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println(">>>MyInterceptor>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
        // 只有返回true才会继续向下执行,返回false取消当前请求
        return true;
    }

}


2)、在spring boot的启动类中配置拦截器的设置,启动类继承WebMvcConfigurerAdapter类,重写addInterceptors方法。注意:// 过滤器、监听器、servlet使用,都需要在启动类上加上@ServletComponentScan注解 @ServletComponentScan

/**
     * 自定义拦截器的配置
     * 
     * @param args
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则
        // excludePathPatterns 用户排除拦截
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }

7.添加文件上传

1)、编写文件上传的controller类

package cn.wt.springboot.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import cn.wt.springboot.utils.FileUtil;

import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;

/**
 * 文件上传
 * 
 * @author wb-wt261136
 * @version 2017年10月18日 下午4:15:31
 */
@Controller
public class SpringBootUploadController {

    /**
     * 文件上传具体实现方法;
     * 
     * @param file @return
     */
    @RequestMapping(value = "/upload", produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {
        if (!file.isEmpty()) {
            try {
                /*
                 * 这段代码执行完毕之后,图片上传到了工程的跟路径; 大家自己扩散下思维,如果我们想把图片上传到 d:/files大家是否能实现呢? 等等;
                 * 这里只是简单一个例子,请自行参考,融入到实际中可能需要大家自己做一些思考,比如: 1、文件路径; 2、文件名; 3、文件格式; 4、文件大小的限制;
                 */
                BufferedOutputStream out = new BufferedOutputStream(
                                                                    new FileOutputStream(
                                                                                         new File(
                                                                                                  file.getOriginalFilename())));
                out.write(file.getBytes());
                out.flush();
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return "上传失败," + e.getMessage();
            } catch (IOException e) {
                e.printStackTrace();
                return "上传失败," + e.getMessage();
            }
            return "上传成功";
        } else {
            return "上传失败,因为文件是空的.";
        }
    }

    /**
     * 多文件具体上传时间,主要是使用了MultipartHttpServletRequest和MultipartFile
     * 
     * @param request @return
     */

    @RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
    public @ResponseBody String handleFileUpload(HttpServletRequest request) {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        MultipartFile file = null;
        BufferedOutputStream stream = null;
        for (int i = 0; i < files.size(); ++i) {
            file = files.get(i);
            if (!file.isEmpty()) {
                try {
                    byte[] bytes = file.getBytes();
                    stream = new BufferedOutputStream(new FileOutputStream(new File(file.getOriginalFilename())));
                    stream.write(bytes);
                    stream.close();
                } catch (Exception e) {
                    stream = null;
                    return "You failed to upload " + i + " =>" + e.getMessage();
                }
            } else {
                return "You failed to upload " + i + " becausethe file was empty.";
            }
        }
        return "upload successful";
    }

    /**
     * 指定位置上传
     * 
     * @param file
     * @param request
     * @return
     */
    @RequestMapping(value = "/target/upload", method = RequestMethod.POST)
    public @ResponseBody String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        String contentType = file.getContentType();
        String fileName = file.getOriginalFilename();
        System.out.println("fileName-->" + fileName);
        System.out.println("getContentType-->" + contentType);
        String filePath = request.getSession().getServletContext().getRealPath("imgupload/");
        try {
            FileUtil.uploadFile(file.getBytes(), filePath, fileName);
        } catch (Exception e) {
        }
        // 返回json
        return "uploadimg success";
    }

}

2)、文件上传工具类

package cn.wt.springboot.utils;

import java.io.File;
import java.io.FileOutputStream;

/**
 * 文件上传工具类
 * 
 * @author wb-wt261136
 * @version 2017年10月18日 下午4:39:43
 */
public class FileUtil {

    public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(filePath + fileName);
        out.write(file);
        out.flush();
        out.close();
    }
}

8.spring boot部署到外部tomcat容器中

1)、在pom文件中添加依赖tomcat依赖,spring-boot-maven-plugin

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
</dependency>

 <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>

2)、在spring boot入口类上继承SpringBootServletInitializer,重写configure方法

@Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(this.getClass());
    }

3)、打包成war包,放入tomcat容器即可。注意:访问的时候要添加上项目名称,才可以正常访问

9.spring boot使用热部署

1)、pom文件中添加依赖:spring-boot-devtools和plugin就可以使用热部署了

<!-- devtools可以实现页面热部署(即页面修改后会立即生效,这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现), 
            实现类文件热部署(类文件修改后不会立即生效),实现对属性文件的热部署。 即devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机),注意:因为其采用的虚拟机机制,该项重启是很快的 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

 <!--  
             用于将应用打成可直接运行的jar(该jar就是用于生产环境中的jar) 值得注意的是,如果没有引用spring-boot-starter-parent做parent,  
                       且采用了上述的第二种方式,这里也要做出相应的改动  
             -->  
            <plugin>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-maven-plugin</artifactId>  
                <configuration>  
                   <!--fork :  如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->  
                    <fork>true</fork>  
                </configuration>  
            </plugin>  

10.spring boot的mock测试resetful风格请求

1)、编写controller类

 @GetMapping("get/{name}")
    public User getUser(@PathVariable String name) {
        return springBootService.getUserByName(name);
    }

    @PostMapping("post")
    public String postUser(User user) {
        springBootService.insertUser(user);
        return "successs";
    }

    @PutMapping("put/{id}")
    public String putUser(@PathVariable int id, User user) {
        user.setId(id);
        springBootService.updateUser(user);
        return "success";
    }

    @DeleteMapping("delete/{id}")
    public String deleteUser(@PathVariable int id) {
        springBootService.deleteUser(id);
        return "success";
    }

2)、编写测试类

package cn.wt.springboot.test;

import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.junit.Test;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.junit.Before;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.web.WebAppConfiguration;
import cn.wt.springboot.SsmSpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.runner.RunWith;

/**
 * @author wb-wt261136
 * @version 2017年10月20日 上午10:16:02
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SsmSpringBootApplication.class)
@WebAppConfiguration
public class MySpringBootMockTest {

    @Autowired
    private WebApplicationContext context;
    private MockMvc               mvc;

    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void mockTest() throws Exception {
        // 查询数据
        String contentAsString = mvc.perform(MockMvcRequestBuilders.get("/get/xh")).andReturn().getResponse().getContentAsString();
        System.out.println(contentAsString);
    }

    @Test
    public void mockTest1() throws Exception {
        // 保存一个数据
        mvc.perform(MockMvcRequestBuilders.post("/post").param("id", "11").param("name", "post").param("sex", "nan").param("city",
                                                                                                                           "shanghai"));
    }

    @Test
    public void mockTest2() throws Exception {
        // 修改一个数据
        mvc.perform(MockMvcRequestBuilders.put("/put/1").param("name", "put").param("sex", "put").param("city", "put"));
    }

    @Test
    public void mockTest3() throws Exception {
        // 删除一个数据
        mvc.perform(MockMvcRequestBuilders.delete("/delete/11"));
    }
}

11.spring boot使用自定义properties

1)、添加依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
</dependency>

2)、在application.properties中添加自定义的配置

#公司简称
com.wt.company.name =知远信科
#公司位置
com.wt.company.location =北京海淀区
#公司联系方式
com.wt.company.mobile = 110****1195
#公司员工人数
com.wt.company.employCount = 100

3)、编写配置类

package cn.wt.springboot.config;

import org.springframework.stereotype.Component;
import org.springframework.boot.context.properties.ConfigurationProperties;

//prefix设置key的前缀;
@ConfigurationProperties(prefix = "com.wt.company")
@Component
public class CompanyProperties {

    private String name;
    private String location;
    private String mobile;
    private int    employCount;

    public String getName() {
        return name;
    }

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

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getMobile() {
        return mobile;
    }

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

    public int getEmployCount() {
        return employCount;
    }

    public void setEmployCount(int employCount) {
        this.employCount = employCount;
    }

    @Override
    public String toString() {
        return "CompanyProperties [name=" + name + ", location=" + location + ", mobile=" + mobile + ", employCount="
               + employCount + "]";
    }
}

4)、使用配置信息,在需要的注入即可


    @Autowired
    private CompanyProperties companyProperties;

    @Test
    public void proTest() {
        System.out.println(companyProperties.getName() + ">>>>" + companyProperties.getLocation());
    }

重要错误:路径不对。输入springboot的访问地址时,将项目名称去电,比如:127.0.0.1:8080/项目名/hello,其中项目名一定要去掉,不能访问不到

⚠️ **GitHub.com Fallback** ⚠️