SpringBoot一些基础常用技术

SpringBoot一些基础常用技术

@RestController和@Controller

@RestController = @Controller + @ResponseBody
1、 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
2、如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
3、如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。

Jackson的基本演绎法

com.fasterxml.jackson.annotation.*
@JsonIgnore:传送json时直接忽略该属性
@JsonFormat:将该属性数据格式化
@JsonInclude

SpringBoot开发环境热部署

使用devtools

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

devtools可以实现页面热部署(即页面修改后会立即生效,这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现)
实现类文件热部署(类文件修改后不会立即生效),并且会立即重启应用(发生在保存时机),注意:因为其采用的虚拟机机制,该项重启是很快的。
为什么重启很快:因为重启的时候只是加载了在开发的class,没有重新加载第三方的jar包。

# 关闭缓存,即时刷新
# spring.thymeleaf.cache=false
spring.thymeleaf.cache=true
# 热部署生效
spring.devtools.restart.enables=true
# 设置重启的目录,添加那个目录的文件需要restart
spring.devtools.restart.additional-paths=src/main/java

# 排除那个目录的文件不需要restart
# spring.devtools.restart.exclude=static/**,public/**

#classpath目录下的WEB-INF文件夹内容修改不重启
# spring.devtools.restart.exclude=WEB-INF/**

SpringBoot资源文件属性配置

添加依赖:

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

@Configuration:配置
@ConfigurationProperties(prefix=""):配置属性的前缀
@PropertySource(value=“classpath:resource.properties”):指定配置文件

SpringBoot资源文件配置server以及tomcat

# 配置端口
server.port=8088
# 配置context-path
server.context-path=/IMooc
# 错误页,指定发生错误时,跳转的URL
server.error.path=/error
# session最大超时时间,默认为30分钟
server.session-timeout=60
# 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败
server.address=192.168.1.2

# Server - tomcat 相关常用配置
############################################################
# Server - tomcat 相关常用配置
############################################################
# tomcat最大线程数, 默认为200
#server.tomcat.max-threads=250
# tomcat的URI编码
server.tomcat.uri-encoding=UTF-8
# 存放Tomcat的日志、Dump等文件的临时文件夹,默认为系统的tmp文件夹
#(如:C:\Users\Shanhy\AppData\Local\Temp)
#server.tomcat.basedir=H:/springboot-tomcat-tmp
# 打开Tomcat的Access日志,并可以设置日志格式的方法:
#server.tomcat.access-log-enabled=true
#server.tomcat.access-log-pattern=
# accesslog目录,默认在basedir/logs
#server.tomcat.accesslog.directory=
# 日志文件目录
#logging.path=H:/springboot-tomcat-tmp
# 日志文件名称,默认为spring.log
#logging.file=myapp.log

SpringBoot整合模板引擎

整合freemarker

添加依赖:

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

配置文件:

############################################################
#
# freemarker 静态资源配置
#
############################################################
#设定ftl文件路径
spring.freemarker.template-loader-path=classpath:/templates
# 关闭缓存, 即时刷新, 上线生产环境需要改为true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl

整合thymeleaf

添加依赖:

<!-- 引入 thymeleaf 模板依赖 -->
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

配置文件:

############################################################
#
# thymeleaf 静态资源配置
#
############################################################
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
# 关闭缓存, 即时刷新, 上线生产环境需要改为true
spring.thymeleaf.cache=false
常用标签的使用方法

条件判断 th:if
th:unless与th:if
循环 th:each
text与utext
th:switch与th:case

SpringBoot配置全局的异常捕获

  • 页面跳转形式
  • ajax形式
  • 统一返回异常的形式
页面跳转形式

定义一个ExceptionHandler用于处理异常:

@ControllerAdvice
public class ErrorExceptionHandler {
	 private static final String LAI_ERROR_VIEW = "error";
	@org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e)throws Exception{
        e.printStackTrace();

        if(isAjax(request)){
            return JSONResult.errorException(e.getMessage());
        }else {
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", request.getRequestURL());
            mav.setViewName(LAI_ERROR_VIEW);
            return mav;
        }
    }
	public static boolean isAjax(HttpServletRequest httpRequest){
        return  (httpRequest.getHeader("X-Requested-With") != null
                && "XMLHttpRequest"
                .equals( httpRequest.getHeader("X-Requested-With").toString()) );
    }
}

再定义一个html用于显示异常界面,如上面的LAI_ERROR_VIEW。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1 style="color: red">发生错误:</h1>
    <div th:text="${url}"></div>
    <div th:text="${exception.message}"></div>
</body>
</html>
ajax形式

与上种形式多增加一个ajax的js文件。

$.ajax({
    url: "/err/getAjaxerror",
    type: "POST",
    async: false,
    success: function(data) {
        debugger;
        if(data.status == 200 && data.msg == "OK") {
            alert("success");
        } else {
            alert("发生异常:" + data.msg);
        }
    },
    error: function (response, ajaxOptions, thrownError) {
        debugger;
        alert("error");
    }
});

Springboot整合mybatis

  • 使用generatorConfig生成mapper以及pojo
  • 实现基于mybatis的CRUD功能
  • 整合mybatis-pagehelper实现分页
  • 自定义mapper的实现
    在application.properties做一些配置:
############################################################
#
# mybatis 配置
#
############################################################
# mybatis 配置
mybatis.type-aliases-package=com.example.springbootdemo.pojo # 实体类生成的文件夹
mybatis.mapper-locations=classpath:mapper/*.xml # 将要存放mapper的文件夹 放在resources目录下
# 通用 Mapper 配置
mapper.mappers=com.example.springbootdemo.utils.MyMapper
mapper.not-empty=false
mapper.identity=MYSQL
# 分页插件配置
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql


############################################################
#
# 配置数据源相关	使用阿里巴巴的 druid 数据源
#
############################################################
spring.datasource.url=jdbc:mysql://1.14.135.123:3306/springdemo
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true

在根目录下创建generatorConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mappers" value="com.imooc.utils.MyMapper"/>
        </plugin>

        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://1.14.135.123:3306/springdemo"
                        userId="root"
                        password="123456">
        </jdbcConnection>

        <!-- 对于生成的pojo所在包 -->
        <javaModelGenerator targetPackage="com.example.springbootdemo.pojo" targetProject="src/main/java"/>

        <!-- 对于生成的mapper所在目录 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>

        <!-- 配置mapper对应的java映射 -->
        <javaClientGenerator targetPackage="com.example.springbootdemo.mapper" targetProject="src/main/java"
                             type="XMLMAPPER"/>


        <table tableName="sys_user"></table>

    </context>
</generatorConfiguration>

根据配置生成对应的文件:

public class GeneratorDisplay {
    public void generator() throws Exception{

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //指定 逆向工程配置文件
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                callback, warnings);
        myBatisGenerator.generate(null);

    }

    public static void main(String[] args) throws Exception {
        try {
            GeneratorDisplay generatorSqlmap = new GeneratorDisplay();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

在SpringBootApplication添加注解:

@MapperScan(basePackages = "com.example.springbootdemo.mapper")

//扫描 所有需要的包, 包含一些自用的工具类包 所在的路径
@ComponentScan(basePackages= {"com.example.springbootdemo", "org.n3r.idworker"})
使用PageHelper分页

示例:

 @Override
    public List<SysUser> queryUserListPaged(SysUser user, Integer page, Integer pageSize) {
        // 开始分页
        PageHelper.startPage(page, pageSize);//page为第几页,pageSize为一页的大小

        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();

        if (!StringUtils.isEmptyOrWhitespace(user.getNickname())) {
            criteria.andLike("nickname", "%" + user.getNickname() + "%");
        }
        example.orderBy("registTime").desc();
        List<SysUser> userList = userMapper.selectByExample(example);

        return userList;
    }
自定义mapper

在java的mapper文件夹中新建一个接口:

public interface SysUserMapperCustom {
	
	List<SysUser> queryUserSimplyInfoById(String id);
}

在resources的mapper文件夹中新建一个mapper:

<?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="com.imooc.mapper.SysUserMapperCustom" >
  
  <!-- 查询简单的用户信息 -->
	<select id="queryUserSimplyInfoById" resultType="com.imooc.pojo.SysUser" 
										 parameterType="java.lang.String" >
	    select 
	    	*
	    from 
	    	sys_user
	    where 
	    	id = #{id,jdbcType=VARCHAR}
	</select>
</mapper>
事务

在增删查改方法加一个注解:

@Transactional(propagation = Propagation.REQUIRED)//增删改

@Transactional(propagation = Propagation.SUPPORTS)//查

SpringBoot整合Redis

添加依赖:

<!-- 引入 redis 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

在application.properties配置(不配则按照默认配置):

############################################################
#
# REDIS 配置
#
############################################################
# Redis数据库索引(默认为0)
spring.redis.database=1
# Redis服务器地址
spring.redis.host=192.168.1.191
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=1000
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=2
# 连接超时时间(毫秒)
spring.redis.timeout=0

使用:

//初始化一个template
@Autowired
private RedisTemplate<String, Object> redisTemplate;

//存入键值对
redisTemplate.opsForValue().set(key, value);

//获取键值对
redisTemplate.opsForValue().get(key);

一个redis的工具类:

public class RedisUtils {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

//	@Autowired
//	private StringRedisTemplate redisTemplate;

    // Key(键),简单的key-value操作

    /**
     * 实现命令:TTL key,以秒为单位,返回给定 key的剩余生存时间(TTL, time to live)。
     *
     * @param key
     * @return
     */
    public long ttl(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 实现命令:expire 设置过期时间,单位秒
     *
     * @param key
     * @return
     */
    public void expire(String key, long timeout) {
        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 实现命令:INCR key,增加key一次
     *
     * @param key
     * @return
     */
    public long incr(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 实现命令:KEYS pattern,查找所有符合给定模式 pattern的 key
     */
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 实现命令:DEL key,删除一个key
     *
     * @param key
     */
    public void del(String key) {
        redisTemplate.delete(key);
    }

    // String(字符串)

    /**
     * 实现命令:SET key value,设置一个key-value(将字符串值 value关联到 key)
     *
     * @param key
     * @param value
     */
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 实现命令:SET key value EX seconds,设置key-value和超时时间(秒)
     *
     * @param key
     * @param value
     * @param timeout
     *            (以秒为单位)
     */
    public void set(String key, String value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * 实现命令:GET key,返回 key所关联的字符串值。
     *
     * @param key
     * @return value
     */
    public String get(String key) {
        return (String)redisTemplate.opsForValue().get(key);
    }

    // Hash(哈希表)

    /**
     * 实现命令:HSET key field value,将哈希表 key中的域 field的值设为 value
     *
     * @param key
     * @param field
     * @param value
     */
    public void hset(String key, String field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    /**
     * 实现命令:HGET key field,返回哈希表 key中给定域 field的值
     *
     * @param key
     * @param field
     * @return
     */
    public String hget(String key, String field) {
        return (String) redisTemplate.opsForHash().get(key, field);
    }

    /**
     * 实现命令:HDEL key field [field ...],删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
     *
     * @param key
     * @param fields
     */
    public void hdel(String key, Object... fields) {
        redisTemplate.opsForHash().delete(key, fields);
    }

    /**
     * 实现命令:HGETALL key,返回哈希表 key中,所有的域和值。
     *
     * @param key
     * @return
     */
    public Map<Object, Object> hgetall(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    // List(列表)

    /**
     * 实现命令:LPUSH key value,将一个值 value插入到列表 key的表头
     *
     * @param key
     * @param value
     * @return 执行 LPUSH命令后,列表的长度。
     */
    public long lpush(String key, String value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * 实现命令:LPOP key,移除并返回列表 key的头元素。
     *
     * @param key
     * @return 列表key的头元素。
     */
    public String lpop(String key) {
        return (String)redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 实现命令:RPUSH key value,将一个值 value插入到列表 key的表尾(最右边)。
     *
     * @param key
     * @param value
     * @return 执行 LPUSH命令后,列表的长度。
     */
    public long rpush(String key, String value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }

}

一个json转换类:

public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}

SpringBoot整合定时任务task

使用注解@EnableScheduling开启定时任务,会自动扫描
定义@Component作为组件被容器扫描
使用@Scheduled(cron = “”)做定时任务。
表达式生成地址:http://cron.qqe2.com

SpringBoot异步执行程序

使用注解@EnableAsync开启异步,会自动扫描。
定义@Component@Async作为组件被容器扫描执行

SpringBoot拦截器的使用

使用注解@Configuration配置拦截器
继承WebMvcCOnfigurerAdapter(已过时),取代的方法有两种:

①implements WebMvcConfigurer(官方推荐)

②extends WebMvcConfigurationSupport
重写addInterceptors添加需要的拦截器地址

@Configuration
public class TestConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /**
         * 拦截器按照顺序执行
         */
//        registry.addInterceptor(new TwoInterceptor()).addPathPatterns("/th/**")
//                .addPathPatterns("/user/**");
        registry.addInterceptor(new OneInterceptor()).addPathPatterns("/user/**");



    }
}

拦截器:

public class OneInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object object) throws Exception {

        System.out.println("被one拦截,放行...");
        return true;

		/*if (true) {
			returnErrorResponse(response, IMoocJSONResult.errorMsg("被one拦截..."));
		}

		return false;*/
    }

    /**
     * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object object, ModelAndView mv)
            throws Exception {
        // TODO Auto-generated method stub

    }

    /**
     * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行
     * (主要是用于进行资源清理工作)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object object, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub

    }

    public void returnErrorResponse(HttpServletResponse response, JSONResult result)
            throws IOException, UnsupportedEncodingException {
        OutputStream out=null;
        try{
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/json");
            out = response.getOutputStream();
            out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
            out.flush();
        } finally{
            if(out!=null){
                out.close();
            }
        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值