SpringBoot入门

springboot常用的技巧

启动springboot方法

1:直接run main方法

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

2:进入到工作目录
执行:mvn spring-boot :run
3:进入工作目录
执行:mvn install
进入target目录:cd target
执行 :java -jar demo-0.0.1-SNAPSHOT.jar

Controller里的注解

@Controller : 只负责跳转页面
@ResponseBody: 跳转页面后返回值
@RestController:跳转页面后返回JSON类型的值
@component: 把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>

@ConfigurationProperties:(prefix = “Girl”)配置文件的信息,读取并自动封装成实体类
@Value:注解来获取配置文件的值
perperties文件如下

@Component
@ConfigurationProperties(prefix = "Girl")
public class GirlProperties {
    private String cupSize;
    private Integer age;
    //省略setter  getter
        @Value("${Age}")
        private Integer age;

.yml文件:需要严格的格式,配置多个yml文件方便维护
application.yml

spring:
  profiles:
##通过active配置,指定对应的配置文件
    active: dev
##数据库连接配置
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/dbgirl
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

application-dev.yml

##指定一个端口
server:
  port: 8080

girl:
  age: 18
  cup-size: F
##content:  "cupSize: ${cupSize}, age: ${Age}"

application-prod.yml

##指定另外的端口
server:
  port: 8081

girl:
  age: 18
  cup-size: D
##content:  "cupSize: ${cupSize}, age: ${Age}"

@Autowire:注解配合setter getter方法获取值

@RequestMapping(value = "/say/{id}"
@PathVariable("id")
//配合获取id的值
@RequestMapping(value = "/say"@PathParam("id")//获取id值
RESTClient 火狐插件POST方法传递参数

1.设置Headers,增加一个
Name:Content-type
Value:application/x-www-form-urlencoded;charset=UTF-8
2.在body中传参数
变量名1=x&变量名2=y
3.对应测试

@GetMapping  @PostMapping
数据的校验@Valid

通过保存的方法来演示
实体类

@Min(value = 18,message = "未成年人")
private Integer age;
方法:使用BindingResult 对象的方法返回错误信息
    @PostMapping(value = "/girls")
    public Girl girlAdd(@Valid Girl girl, BindingResult bindingResult){
    if(bindingResult.hasErrors()){
    //使用BindingResult返回错误信息          
    System.out.println(bindingResult.getFieldError()
                .getDefaultMessage());
            return null;
        }
        girl.setCupSize(girl.getCupSize());
        girl.setAge(girl.getAge());
        return girlResponsitory.save(girl);
改进一:上述方法返回的数据格式不一致,定义一个Result对象封装返回的信息,统一格式
定义Result对象
public class Result<T> {
    /** 错误码  */
    private Integer code;
    //提示信息
    private String msg;
    //具体内容
    private T data;
 //省略setter  getter 方法
 }

改进方法

    @PostMapping(value = "/girls")
    public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            Result result = new Result();
            result.setCode(1);
            result.setMsg(bindingResult.getFieldError().getDefaultMessage());
            result.setData(null);
            return result;
        }
        girl.setCupSize(girl.getCupSize());
        girl.setAge(girl.getAge());
        Result result = new Result();
        result.setCode(0);
        result.setMsg("成功");
        result.setData(girl);
        return result;
    }
改进二:上述的方法重复代码太多了,写个工具类ResultUtills
public class ResultUtills {
    public static Result success(Object object){
        Result result = new Result();
        result.setCode(0);
        result.setMsg("成功");
        result.setData(object);
        return result;
    }
    public static Result success(){
        return  success(null);
    }
    public static Result error(Integer code, String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return  result;
    }
}

改进二的方法

    @PostMapping(value = "/girls")
    public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return ResultUtills.error(1,bindingResult.getFieldError().getDefaultMessage());
        }

        return ResultUtills.success(girlResponsitory.save(girl));
    }
AOP切面编程,重点log日志打印的使用

AOP的注解实现
一:@Pointcut定义切入点 拦截包下*方法
二:@Before(“log()”)等方法调用切入点
三:Logger 的使用 slf4j的 Logger
四:logger.info()的格式

    private final static Logger logger =   LoggerFactory.getLogger(HttpAspect.class);
    @Pointcut("execution(public * com.girl.demo.Controller.GirlController.*(..))")
    public void log(){
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){

        ServletRequestAttributes servletRequestAttributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request =  servletRequestAttributes.getRequest();
        //URL
        logger.info("URl={}",request.getRequestURL());
        //method
        logger.info("method={}",request.getMethod());
        //ip
        logger.info("ip={}",request.getRemoteAddr());
        //类方法
        logger.info("ClassMethod={}",joinPoint.getSignature().getDeclaringTypeName());
        //参数
        logger.info("param={}",joinPoint.getArgs());
    }

    @After("log()")
    public void doAfter(){
        logger.info("iiiiiiiiii");
    }
    @AfterReturning(returning ="obj",pointcut = "log()")
    public void doAfterReturn(Object obj){
        //方法执行之后  返回结果
        logger.info("response={}",obj.toString());
    }
统一异常处理:返回的不是一种类型,不能单纯返回值类型是String

1 首先采用Result对象,固定三个字段
2 为了解决逻辑在一个地方处理,另外的地方不用再接收它返回的信息,引入异常
3 默认的Exception 只接受msg字段,但是还有code,因此定义自己的异常类GirlException
4 有了异常,需要捕获,写了捕获异常类:ExceptionHandlers
5 最后将 code msg 字段定义成枚举统一管理
6 在Service中处理逻辑,若验证不通过的话,直接抛出异常
Controller中直接调用Service中的方法,也抛出异常
类ExceptionHandlers 接收异常并且处理异常

以查询 方法为例子
public void getAge(Integer id) throws Exception{
        Girl girl = girlResponsitory.findOne(id);
        if(girl.getAge() < 10){
        //返回小学生,code=100
        throw new GirlException(100,"小学生");
        }
改进方法:

异常处理类

@ControllerAdvice
public class ExceptionHandlers {
    //记录下异常
    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandlers.class);
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result handl(Exception e){
        /**
         * 捕获异常,判断code是100还是101
         */
        if (e instanceof GirlException) {
            GirlException girlException = (GirlException)e;
            return ResultUtills.error(girlException.getCode(),girlException.getMessage());
        }else{
            //logger的使用 格式("【系统异常】{}",e),内容会出现在{}里面
            logger.info("【系统异常】{}",e);
            return ResultUtills.error(-1,"未知错误");
        }

    }
}

查询方法

 public void getAge(Integer id) throws Exception{
        Girl girl = girlResponsitory.findOne(id);
        if(girl.getAge() < 10){
        //构造Exception方法,传入message
        //改进  使用枚举类型便于维护
        throw new GirlException(ResultEnums.PRIMARY_SCHOOL);
        else  if(girl.getAge() >10 && girl.getAge() <16){
            //返回初中生,code=101
            throw  new GirlException(ResultEnums.MIDDLE_SCHOOL);
        }

枚举的使用

/**
 * 枚举的使用,便于后期的维护
 *
 */
public enum ResultEnums {
    UNKUNOW_ERROR(-1,"未知错误"),
    SUCCESS(0,"成功"),
    PRIMARY_SCHOOL(100,"上小学"),
    MIDDLE_SCHOOL(101,"上初中")
    ;
    private Integer code;
    private  String msg;
    ResultEnums(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

实现RuntimeException

public class GirlException extends RuntimeException {
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
//构造方法里  传入message
    /*public GirlException(Integer code ,String message) {
        super(message);
        this.code = code;
    }*/

    //改进  传入枚举类型的  构造方法
    public GirlException(ResultEnums resultEnums) {
        super(resultEnums.getMsg());
        this.code = resultEnums.getCode();
    }
}
单元测试

1测试Service
2测试带有URL的测试
3在powershell中进入工作目录 mvn clean package 直接测试所有的TEST
跳过错误的测试 mvn clean package -Dmaven .test.skip=true

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值