使用IDEA基于springboot开发ssm框架(undertow代替tomcat以及其他功能)

在这里,第二次使用springboot开发,看过我之前的文章可知。因为spirngboot是去除xml等繁琐配置,大部分内容都已经帮你设置好,因此需要有一定的spring基础才能学习,不然不明白原理会难以下手。

文档结构图
这里写图片描述
这里写图片描述

1. pom.xml需要引入的依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--事务处理-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
            <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </exclusion>
        </exclusions>
        </dependency>

        <!--数据库连接池-->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>

        <!--断点上传工具-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!--<exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>-->
        </dependency>

        <!--undertow服务器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <!--打包时的名字-->
        <finalName>webApp</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <!--打包时跳过单元测试类-->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

2. application.yml中相关配置

spring:
  datasource:
    hikari:
      username: root
      password: ####
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
      max-lifetime: 176500
      maximum-pool-size: 15
      connection-timeout: 30000
  redis:
    host: 192.168.110.130
    port: 6379
    password: ####
    timeout: 500    #超时时间
    pool:
      maxWaitMillis: -1   #连接池最大阻塞等待时间(使用负值表示没有限制)
      maxIdle: 8   #最大空闲连接


server:
  undertow:
    buffer-size: 1024
    direct-buffers: true



#DEBUG模式
logging:
  level: debug

3. Main主函数入口相关配置


@Configuration
@Controller
@ComponentScan(basePackages = "com.example.demo") //扫描注解
@MapperScan("com.example.demo.dao")  //扫描接口
@SpringBootApplication //开启初始化配置,必须有
@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
@EnableTransactionManagement //开启事务
@EnableCaching //开启缓存
public class DemoApplication {

    @Autowired
    private UserService userService;

    @RequestMapping("/index")
    public String index(){
        return "index";
    }

    /*@Bean
    public StringHttpMessageConverter stringHttpMessageConverter(){
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("ISO-8859-1"));
        return stringHttpMessageConverter;
    }
    spring boot默认使用utf-8的消息转发器,这里可以进行覆盖测试
    */
    @RequestMapping("/upload")
    public  @ResponseBody String upload(@RequestParam("files")MultipartFile[] files) throws Exception{
        String path = "E:\\upload\\";
        for(int i = 0;i<files.length;i++){
            if(!files[i].isEmpty()){
                String filename = files[i].getOriginalFilename();
                String new_filename = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."));
                File f = new File(path + new_filename);
//            System.out.println(f.toString());
                files[i].transferTo(f);//sd
            }
        }
        return "up success";
    }

    @RequestMapping("/download")
    public String download(HttpServletResponse response){
        String filename = "test.pdf";
        response.setHeader("content-type","application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition","attachment;filename="+filename);
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(new File("E:\\upload\\"+filename)));
            int i;
            while((i = bis.read(buff)) != -1){
                os.write(buff,0,buff.length);
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                os.close();
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "down success";
    }

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

4. 自定义Config相关配置

  • Hikari配置
@Configuration
public class HikariConfig {

    /*如果有其他需求可以在这里配置*/
    @Bean
    @ConfigurationProperties(prefix = "spring.dataSource.hikari")
    public DataSource dataSource(){
        HikariDataSource hikariDataSource = new HikariDataSource();
//        hikariDataSource.setConnectionTimeout(50000);优先级没有application.yml高
        System.out.println("Hikari加载成功");
        return hikariDataSource;
    }
}
  • 拦截器配置
//自定义拦截器,继承WebMvcConfigurerAdapter并且重写addInterceptors方法,然后添加拦截策略
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter{

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        System.out.println("CustomInterceptor加载成功");
        registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/**");
    }
}
  • 文件上传配置
@Configuration
public class MultipartConfig {

    @Bean
    public MultipartResolver multipartResolver(){
        CustomMultipartResolver resolver = new CustomMultipartResolver();
        System.out.println("CustomMultipartResolver加载成功");
        resolver.setMaxUploadSize(1024*1024*100);//5MB
        return resolver;
    }

}
  • mybatis配置
@Configuration
public class MybatisConfig {
    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        System.out.println("SqlSessionFactoryBean加载成功");
        return sqlSessionFactoryBean;
    }
}
  • redis配置
@Configuration
public class RedisConfig extends CachingConfigurerSupport{

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.pool.maxIdle}")
    private int maxIdle;

    @Value("${spring.redis.pool.maxWaitMillis}")
    private int maxWaitMillis;

    @Bean
    public JedisPool jedisPool(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMinIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,password);
        System.out.println("jedis配置完成");
        return jedisPool;
    }
}
  • undertow配置
@Configuration
public class UndertowConfig {
    @Bean
    @ConfigurationProperties(prefix = "server.undertow")
    public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory(){
        UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
        System.out.println("undertow加载成功");
//        factory.setPort(8088);
        return factory;
    }

}

5. 拦截器类

public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("拦截在这儿");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

6. 文件断点上传类

  • 监听条
@Component
public class FileUpLoadProgressListener implements ProgressListener {
    private HttpSession session;

    public void setSession(HttpSession session){
        this.session = session;
        ProgressEntity status = new ProgressEntity();
        session.setAttribute("status",status);
    }

    @Override
    public void update(long nowByte, long process, int count) {
        ProgressEntity progressEntity = (ProgressEntity) session.getAttribute("status");
        progressEntity.setUpByte(nowByte);
        progressEntity.setUpSize(process);
        progressEntity.setUpItems(count);
        System.out.println("装载文件上传内容。。。" + progressEntity);
    }
}
  • 继承重写
public class CustomMultipartResolver extends CommonsMultipartResolver{

    @Autowired
    private  FileUpLoadProgressListener listener;

    @Override
    protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
        String encoding = determineEncoding(request);
        FileUpload fileUpload = prepareFileUpload(encoding);
        listener.setSession(request.getSession());
        fileUpload.setProgressListener(listener);
        try {
            List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
            return parseFileItems(fileItems,encoding);
        } catch (FileUploadBase.SizeLimitExceededException ex) {
            throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
        }
        catch (FileUploadBase.FileSizeLimitExceededException ex) {
            throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex);
        }
        catch (FileUploadException ex) {
            throw new MultipartException("Failed to parse multipart servlet request", ex);
        }
    }
}

7. 自定义全局异常类

@ControllerAdvice
public class GlobalException {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Map<String,Object> exceptionHandler(Model model){
        HashMap<String, Object> result = new HashMap<>();
        result.put("code",500);
        result.put("message","亲,系统错误请稍后重试...");
        //返回json格式
        return result;
    }
}

8. dao层配置

  • mybatis
@Mapper
public interface UserMapper {

    @Select("SELECT * FROM user")
    public List<User> selectAll();
}
  • redis
@Repository
public class RedisClient {
    @Autowired
    private JedisPool jedisPool;

    public void addJsonData(String key,String target){
        jedisPool.getResource().set(key,target);
    }

    public boolean isExistKey(String key){
        Boolean result = jedisPool.getResource().exists(key);
        return result;
    }

}

9. 实体类配置

  • ProgressEntity
//涉及流,需要序列化
public class ProgressEntity implements Serializable{

    private long upByte = 0L;
    private long upSize = 0L;
    private int upItems;

    @Override
    public String toString() {
        return "ProgressEntity{" +
                "upByte=" + upByte +
                ", upSize=" + upSize +
                ", upItems=" + upItems +
                '}';
    }

    public long getUpByte() {
        return upByte;
    }

    public void setUpByte(long upByte) {
        this.upByte = upByte;
    }

    public long getUpSize() {
        return upSize;
    }

    public void setUpSize(long upSize) {
        this.upSize = upSize;
    }

    public int getUpItems() {
        return upItems;
    }

    public void setUpItems(int upItems) {
        this.upItems = upItems;
    }
}
  • User

public class User implements Serializable{
    private int id;
    private String userName;
    private String address;
    private Date date;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", address='" + address + '\'' +
                ", date=" + date +
                '}';
    }

    public int getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAddress() {
        return address;
    }

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

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

10. service层配置

@Service
//@Transactional //这个注解可以加在类和方法,方法上说明此方法使用事务
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisClient redisClient;

    /*测试redis缓存*/
    @Transactional(propagation = Propagation.SUPPORTS)
    @Cacheable(value = "getAllUsers") //在getAllUsers找缓存
    public List<User> getAllUsers(){
        System.out.println("如果第二次没有打印,说明缓存存在");
       return userMapper.selectAll();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @CacheEvict(value = "getAllUsers")//CacheEvict去除缓存,CachePut加入缓存
    public void flushAllUsers(){
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void addJson(String key,String target){
        redisClient.addJsonData(key,target);
    }
}

11. 测试结果

  • 访问index
    访问index
  • 断点上传
    断点上传
  • 下载
    下载

猜你喜欢

转载自blog.csdn.net/a568283992/article/details/79082033
今日推荐