springboot-20190814

118 阅读3分钟

注:知识比较杂乱,只是把学到了都写下来了

  1. 统一的参数校验
  • 目的:为了避免在业务层中做冗长的if-else,抛出异常等动作,采用springboot中的javax.validation注解式。

    • 步骤: (1)引入依赖包

      <!--JSR303-->
      <dependency>
          <groupId>javax.validation</groupId>
          <artifactId>validation-api</artifactId>
          <version>2.0.1.Final</version>
      </dependency>
      <!-- hibernate validator-->
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator</artifactId>
          <version>5.2.0.Final</version>
      </dependency>
      

      (2)创建实体类

      /**
       * 用户id
       */
      @Id
      @NotNull(message = "id不能为空")
      private Integer id;
      
      /**
       * 用户姓名
       */
      @NotNull(message = "用户名不能为空")
      @Length(max = 20,message = "当前用户名长度不能超过20个字符")
      @Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$",message = "用户名包含	文字,字母和数字")
      private String name;
      

    注:常用的注释 @Email:校验邮箱格式 @Future:时间只能是将来时间 @NotNull:不能为null,但可以为空 @NotEmpty:不能为null,但长度必须大于0 @NotBlank:不能为null,只能作用在String类型上

    (3)测试就省略了... (4)过程中出现了不少错误,是由于validation-api与hibernate-validator的版本不匹配造成的

  1. 全局异常处理
  • 目的:避免繁琐的捕获异常,同时,发生异常之后程序还能继续执行。
  • 首先这里要谈到shiro安全框架,
  • 自定义全局异常类,要使用@ControllerAdvice/@RestControllerAdvice,控制器增强
  • @ExceptionHandler(xxx.class)可以捕获该类的异常
  • 代码 (1)自定义异常类
    	public class RRException extends RuntimeException {
    		private static final long serialVersionUID = 1L;
    		
    	    private String msg;
    	    private int code = 500;
    	    
    	    public RRException(String msg) {
    			super(msg);
    			this.msg = msg;
    		}
    		
    		public RRException(String msg, Throwable e) {
    			super(msg, e);
    			this.msg = msg;
    		}
    		
    		public RRException(String msg, int code) {
    			super(msg);
    			this.msg = msg;
    			this.code = code;
    		}
    		
    		public RRException(String msg, int code, Throwable e) {
    			super(msg, e);
    			this.msg = msg;
    			this.code = code;
    		}
    	
    		public String getMsg() {
    			return msg;
    		}
    	
    		public void setMsg(String msg) {
    			this.msg = msg;
    		}
    	
    		public int getCode() {
    			return code;
    		}
    	
    		public void setCode(int code) {
    			this.code = code;
    		}
    		
    }
    
    
    (2)异常处理器
    	@RestControllerAdvice
    	public class RRExceptionHandler {
    		private Logger logger = LoggerFactory.getLogger(getClass());
    	
    		/**
    		 * 处理自定义异常
    		 */
    		@ExceptionHandler(RRException.class)
    		public R handleRRException(RRException e){
    			R r = new R();
    			r.put("code", e.getCode());
    			r.put("msg", e.getMessage());
    	
    			return r;
    		}
    	
    		@ExceptionHandler(NoHandlerFoundException.class)
    		public R handlerNoFoundException(Exception e) {
    			logger.error(e.getMessage(), e);
    			return R.error(404, "路径不存在,请检查路径是否正确");
    		}
    	
    		@ExceptionHandler(DuplicateKeyException.class)
    		public R handleDuplicateKeyException(DuplicateKeyException e){
    			logger.error(e.getMessage(), e);
    			return R.error("数据库中已存在该记录");
    		}
    	
    		@ExceptionHandler(AuthorizationException.class)
    		public R handleAuthorizationException(AuthorizationException e){
    			logger.error(e.getMessage(), e);
    			return R.error("没有权限,请联系管理员授权");
    		}
    	
    		@ExceptionHandler(Exception.class)
    		public R handleException(Exception e){
    			logger.error(e.getMessage(), e);
    			return R.error();
    		}
    	}
    
    
    (3)返回数据
    	public class R extends HashMap<String, Object> {
    		private static final long serialVersionUID = 1L;
    		
    		public R() {
    			put("Svc_Rsp_St", "00");
    			put("Svc_Rsp_CD", "100001");
    			put("Sign_inf", "");
    		}
    		
    		public static R error() {
    			return error("系统错误");
    		}
    		
    		public static R error(String msg) {
    			R r = new R();
    			r.put("Svc_Rsp_CD", "200001");
    			r.put("Svc_Rsp_St", "01");
    			r.put("Rsp_Inf",msg);
    			r.put("Sign_inf", "");
    			return r;
    		}
    		
    		public static R error(int code, String msg) {
    			R r = new R();
    			r.put("Svc_Rsp_St", "01");
    			r.put("Svc_Rsp_CD", "200001");
    			r.put("Sign_inf", "");
    			r.put("Rsp_Inf", msg);
    			return r;
    		}
    	
    		public static R ok(String msg) {
    			R r = new R();
    			r.put("Rsp_Inf", msg);
    			return r;
    		}
    		
    		public static R ok(Map<String, Object> map) {
    			R r = new R();
    			r.putAll(map);
    			return r;
    		}
    		
    		public static R ok() {
    			return new R();
    		}
    	
    		public R put(String key, Object value) {
    			super.put(key, value);
    			return this;
    		}
    	}
    
    
    (4)大功告成啦~
    	return R.ok();
    	return R.ok("success");
    	return R.error();
    	...
    

来源不太记得了,侵删,感谢博主的分享。

  1. springboot中使用https

(1) 简易生成https证书的方法:

  在Java/bin目录下,输入:keytool -genkey -alias tomcathttps -keyalg RSA - keysize 2048 -keystore D:\javaboy.p12 -validity 365

- genkey 表示要创建一个新的密钥。
- alias 表示 keystore 的别名。
- keyalg 表示使用的加密算法是 RSA ,一种非对称加密算法。
- keysize 表示密钥的长度。
- keystore 表示生成的密钥存放位置。
- validity 表示密钥的有效时间,单位为天。

(2) 启动项目之后,正常访问,正常返回结果 (3) 将证书发放入resourses目录下,并在application.yml中配置如下,重启项目

(4) 结果:Bad Request This combination of host and port requires TLS.     用 https 访问,正常.

  1. 请求转发
  • 目的:springboot中不同时支持http和https,所以需要做一个请求转发,支持同时调用http和https。
  • 步骤: (1)修改application.yml,一定要记得改!
    (2)配置TomcatConfig
    @Configuration
    public class TomcatConfig {
        @Bean
        public ServletWebServerFactory servletContainer() {
            TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
            tomcat.addAdditionalTomcatConnectors(createHTTPConnector());
            return tomcat;
        }
    
        private Connector createHTTPConnector() {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setScheme("http");
            connector.setSecure(false);
            connector.setPort(8088);
            connector.setRedirectPort(8089);
            return connector;
        }
    }
    

(3)访问路径:

http://localhost:8088/...

https://localhost:8089/...

(4)大功告成啦~

侵删,来源:juejin.cn/post/684490…