From c6018b21d1f0f2fd97803bd0e616d577efa40052 Mon Sep 17 00:00:00 2001 From: lsy <18332763730@163.com> Date: Sat, 21 Oct 2017 14:08:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boot-starter-security-core/pom.xml | 8 +- .../boot-starter-security-demo/README.md | 1 + .../ControllerExceptionHandler.java | 19 +++++ .../demo/controller/RestfulController.java | 62 ++++++++++++++ .../demo/controller/package-info.java | 1 + .../exception/UserNotExistsException.java | 21 +++++ .../micro/fast/security/demo/pojo/User.java | 77 +++++++++++++++++ .../demo/validator/MyConstrainValidator.java | 28 +++++++ .../security/demo/validator/MyContraint.java | 21 +++++ .../src/main/resources/application.yml | 3 + .../src/main/resources/error/404.html | 10 +++ ...otStarterSecurityDemoApplicationTests.java | 82 +++++++++++++++++++ 12 files changed, 329 insertions(+), 4 deletions(-) create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/ControllerExceptionHandler.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/RestfulController.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/package-info.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/exception/UserNotExistsException.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/pojo/User.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyConstrainValidator.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyContraint.java create mode 100644 boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/error/404.html diff --git a/boot-starter/boot-starter-security/boot-starter-security-core/pom.xml b/boot-starter/boot-starter-security/boot-starter-security-core/pom.xml index f2a85d4..e3f321b 100644 --- a/boot-starter/boot-starter-security/boot-starter-security-core/pom.xml +++ b/boot-starter/boot-starter-security/boot-starter-security-core/pom.xml @@ -20,10 +20,10 @@ org.springframework.cloud spring-cloud-starter-oauth2 - - - - + + org.springframework.boot + spring-boot-starter-data-redis + org.springframework.boot spring-boot-starter-jdbc diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/README.md b/boot-starter/boot-starter-security/boot-starter-security-demo/README.md index e69de29..8b13789 100644 --- a/boot-starter/boot-starter-security/boot-starter-security-demo/README.md +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/README.md @@ -0,0 +1 @@ + diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/ControllerExceptionHandler.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/ControllerExceptionHandler.java new file mode 100644 index 0000000..d6a7048 --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/ControllerExceptionHandler.java @@ -0,0 +1,19 @@ +package com.micro.fast.security.demo.controller; + +import com.micro.fast.security.demo.exception.UserNotExistsException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +//异常处理类 +@RestControllerAdvice +public class ControllerExceptionHandler{ + + //处理UserNotExists异常,当app调用的时候返回这里的信息 + @ExceptionHandler(UserNotExistsException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//定义返回的http状态码 + public Map handlerUserNotExitsHandler(UserNotExistsException ex){ + return null; + } +} \ No newline at end of file diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/RestfulController.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/RestfulController.java new file mode 100644 index 0000000..76683af --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/RestfulController.java @@ -0,0 +1,62 @@ +package com.micro.fast.security.demo.controller; + +import com.fasterxml.jackson.annotation.JsonView; +import com.micro.fast.security.demo.pojo.User; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/user") +public class RestfulController { + + @GetMapping("/{id:\\d+}")//使用正则表达式指定传入的参数只能是数字 + @JsonView(User.DetailView.class) + public User getInfo(@PathVariable("id") String id){ + User user = new User("tom"); + return user; + } + + @GetMapping + @JsonView(User.SimpleView.class) + public List query(@RequestParam("username") String username){ + List users = new ArrayList<>(); + users.add(new User("name")); + users.add(new User("name")); + users.add(new User("name")); + return users; + } + + /** + * 不写视图解析器的JsonView的话就是显示所有的字段 @Valid配合pojo上的注解进行校验不写这个注解的话就不会执行校验逻辑,如果不写BindingResult参数的话, + * 参数校验不合法的话就不会进入方法体里面,直接报400错误 + * @param user + * @param errors + * @return + */ + @PostMapping + public User createUser(@Valid @RequestBody User user, BindingResult errors){ + if (errors.hasErrors()){ + //如果有错误信息的话就打印出错误信息 + errors.getAllErrors().stream().forEach(error->{ + System.out.println(error.getDefaultMessage()); + FieldError fieldError = (FieldError) error; + //错误中输出字段名字 + String s = fieldError.getField() + error.getDefaultMessage(); + //输出检验错误的字段的名字 + System.out.println(s); + }); + } + + System.out.println(user.getName()); + System.out.println(user.getPassword()); + System.out.println(user.getBirthday()); + return user; + } + + +} diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/package-info.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/package-info.java new file mode 100644 index 0000000..73d5fef --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/controller/package-info.java @@ -0,0 +1 @@ +package com.micro.fast.security.demo.controller; \ No newline at end of file diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/exception/UserNotExistsException.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/exception/UserNotExistsException.java new file mode 100644 index 0000000..3f520ee --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/exception/UserNotExistsException.java @@ -0,0 +1,21 @@ +package com.micro.fast.security.demo.exception; + +/** + * 自定义异常,传入详细的异常信息 + */ +public class UserNotExistsException extends RuntimeException { + + private String id; + public UserNotExistsException(String id){ + super("user not exist"); + this.id=id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/pojo/User.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/pojo/User.java new file mode 100644 index 0000000..fd20511 --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/pojo/User.java @@ -0,0 +1,77 @@ +package com.micro.fast.security.demo.pojo; + +import com.fasterxml.jackson.annotation.JsonView; +import org.hibernate.validator.constraints.*; + +import javax.validation.constraints.*; +import java.util.Date; + +/** + * 使用jsonView和接口来声明多个视图 + * 在查询方法上指定视图 + */ +public class User { + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public interface SimpleView{}; + public interface DetailView extends SimpleView{}; + + @JsonView(SimpleView.class) + private String name; + + @JsonView(DetailView.class) + @NotBlank(message = "用户密码不能为空")//参数校验,使用message自定义校验返回的错误信息 + private String password; + + @JsonView(SimpleView.class) + @NotBlank//hibernate valid + @NotNull + @NotEmpty//字符串不能为空,集合不能为空 + @Size(min = 1,max = 20)//检验集合元素的个数 + @Email + @Pattern(regexp = "a{0,1}") + @CreditCardNumber()//是否是美国的银行卡号 + @Length(min = 1,max = 100)//校验字符串的航渡 + @Range(min = 1,max = 2)//检验数字的值 + @SafeHtml//检验字符串是安全的html + @URL//检验字符串是安全的html + @AssertFalse + @AssertTrue + @DecimalMax(value = "1.00",inclusive = true)//小于等于 可以修饰在字符串上 + @DecimalMin(value = "2.00",inclusive = false)//大于等于 可以修饰在字符串上 + @Digits(integer = 1,fraction = 2)//校验数字的格式 integer指定整数部分的长度 fraction指定小数部分的长度 + @Past //日期必须是过去的日期 +// @Future 日期必须是未来的日期 + @Max(value = 1)//最大值 小于等于 不能注解在字符串上 + @Min(2) //最小值 大于等于 不能注解在字符串上 + private Date birthday; + + public User() { + } + + public User(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyConstrainValidator.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyConstrainValidator.java new file mode 100644 index 0000000..49ac9e3 --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyConstrainValidator.java @@ -0,0 +1,28 @@ +package com.micro.fast.security.demo.validator; + + +import org.springframework.stereotype.Component; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * MyContraint 注解的类型, + * String 要对什么类型的字段进行校验 + */ +@Component +public class MyConstrainValidator implements ConstraintValidator { + + //@Autowired 注入Service + //private String name; + @Override + public void initialize(MyContraint myContraint) { + System.out.println("初始化校验器"); + } + + @Override + public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { + //校验的逻辑 + return false; + } +} diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyContraint.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyContraint.java new file mode 100644 index 0000000..cd17570 --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/java/com/micro/fast/security/demo/validator/MyContraint.java @@ -0,0 +1,21 @@ +package com.micro.fast.security.demo.validator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +/** + * 自定义注解 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD,ElementType.METHOD}) +@Inherited +@Documented +@Constraint(validatedBy = MyConstrainValidator.class)//指明校验逻辑的类 +public @interface MyContraint { + String message() ;//校验的失败的时候返回的信息 + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/application.yml b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/application.yml index 54a1d1e..27d00e4 100644 --- a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/application.yml +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/application.yml @@ -6,6 +6,9 @@ spring: username: root password: studyj2e driver-class-name: com.mysql.jdbc.Driver + redis: + host: 127.0.0.1 + port: 6379 security: basic: enabled: false diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/error/404.html b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/error/404.html new file mode 100644 index 0000000..8879291 --- /dev/null +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/main/resources/error/404.html @@ -0,0 +1,10 @@ + + + + + 404 + + +

你所访问的页面不存在,对浏览器返回此页面,对app返回的信息是json信息

+ + \ No newline at end of file diff --git a/boot-starter/boot-starter-security/boot-starter-security-demo/src/test/java/com/micro/fast/security/demo/BootStarterSecurityDemoApplicationTests.java b/boot-starter/boot-starter-security/boot-starter-security-demo/src/test/java/com/micro/fast/security/demo/BootStarterSecurityDemoApplicationTests.java index c67c6af..7003baa 100644 --- a/boot-starter/boot-starter-security/boot-starter-security-demo/src/test/java/com/micro/fast/security/demo/BootStarterSecurityDemoApplicationTests.java +++ b/boot-starter/boot-starter-security/boot-starter-security-demo/src/test/java/com/micro/fast/security/demo/BootStarterSecurityDemoApplicationTests.java @@ -1,9 +1,21 @@ package com.micro.fast.security.demo; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; @RunWith(SpringRunner.class) @SpringBootTest @@ -13,4 +25,74 @@ public class BootStarterSecurityDemoApplicationTests { public void contextLoads() { } + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + /** + * 在每次测试执行前构建mvc环境 + */ + @Before + public void setup(){ + mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } + + /** + * 用户信息查询 + */ + @Test + public void whenQuerySuccess(){ + //测试接口的返回结果是否满足预期 + try { + mockMvc.perform(MockMvcRequestBuilders.get("/user").param("username","pojo") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk())//检查状态码 + .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));//检查集合的长度是3个 + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 获取用户的信息详情 + */ + @Test + public void whenGetInfoSuccess(){ + try { + mockMvc.perform(MockMvcRequestBuilders.get("/user/1") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("tom")); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 创建用户 + */ + @Test + public void whenCreateSuccess(){ + //前台传入的是长整形 + Date date = new Date(); + String content = "{\"name\":\"tom\",\"password\":\"\",\"birthday\":"+date.getTime()+"}"; + try { + String tom = mockMvc.perform(MockMvcRequestBuilders.post("/user") + .contentType(MediaType.APPLICATION_JSON_UTF8).content(content)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("tom")) + .andReturn().getResponse().getContentAsString(); + //后台返回的日期格式也是长整形 + System.out.println(tom); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void whenUpdateSuccess(){ + //本地的时间加1年 + Date date = new Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + + } }