Note.Ver_2019.8.14(Spring boot/Vue/原型设计)

引言

进企业实习的学习效率非常之高,分享笔记,希望大家共同进步。


知识点

1. Spring boot
  • 面向接口编程
    由于Spring boot的自动注入IOC容器的存在,之前对调用接口不是太理解。在JPA中体现比较多,调用JPA接口即可调用方法。
// User.java
public interface UserService{
	String getInfo();
}
// UserImpl.java
@Component
public class UserServiceImpl implements UserService{
	public String getInfo(){
		System.out.println("User");
		return "Success";
	}
}
// UserController.java
@Controller
public class UserController{
	// 自动注入接口的实现类
	@Autowired
	private UserService userService;
	
	@GetMapping("/getInfo")
	public String getUserInfo(){
		return userService.getInfo();
	}
}
  • 面向AOP切面编程
    Spring boot中多用注解的形式实现功能增强,利用代理模式实现切面增强,具体原理代码还在学习中…

  • 传值参数校验(@Valid )
    利用javax.validation.Valid 即 @Valid注解来解决参数校验的问题:

// UserVO.java
/*
   参数接受类
*/
@Data
public class UserVO{
	private Long id;
	@NotBlank
	@Length(min = 4,max = 12, message = "用户名长度不符合要求!")
    private String username;
    @NotBlank
    @Length(min = 6,max = 18, message = "密码长度范围需要在6-18个范围内!")
    private String password;
    
    public User createEntity() {
        User user = new User();
        BeanUtils.copyProperties(this, user);
        return user;
    }
}

// UserController.java
@RestController
@RequestMapping("/user")
public class UserController{
	// 方法一:手动处理验证错误
	@PostMapping("/create")
	public String saveUser(@Valid @RequestBody UserVO userVO,BindingResult br){
		if (br.hasErrors()){
            throw new ValidationException("数据不规范!");
        }
        return "Success";
	}
	// 方法二:不进行主动处理,抛出MethodArgumentNotValidException异常
	@PostMapping("/create")
	public String saveUser(@Valid @RequestBody UserVO userVO){
        return "Success";
	}
}

// 统一处理异常
// ExerciseExceptionHandler.js
@ControllerAdvice
@Slf4j
@Order(ExerciseExceptionHandler.Order.GLOBAL_PRECEDENCE)
public class ExerciseExceptionHandler {
	@ExceptionHandler(ValidationException.class)
    @ResponseBody
    public ResponseMessage handleValidationException(ValidationException be) {
        HashMap<String,Object> resp = new HashMap<>();
        resp.put("status",500);
        resp.put("msg",be.getMessage());
        return resp;
    }
}
  • JWT (json web token)
    网站系统单点登录解决方案,与其说它是方案,不如说是标准。相对于Session来说,其不申请内存空间,自带信息。基于这一特点,便可以做到跨域访问,token接收者只需要用加密盐key去解密进行身份核实即可。
    其分为三段内容:
  • Header
  • Payload
  • Signature

jwt = Base64url(Header).Base64url(Payload).Signature
Signature = HS256(Header.Payload)

// Header
{
	"alg":"HS256", // 签名算法
	"typ":"JWT"    //类型
}
// Payload
{
	// 规范中的字段
	"jti":   //唯一标识
	"sub":   //该JWT的主题
	"aud":   //该JWT面向的用户
	"iss":   //该JWT的签发者
	"iat":   //该JWT的签发时间
	"exp":   //该JWT的过期时间
	"nbf":   //该JWT在该时间之前不能被接收处理

	// data数据部分,自定义
	"username": 
	... ...
}
// Signature 加盐加密前两段数据

先给出一个小demo,之后会完善:

<!--pom.xml -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
#application.yml
jwt-util:
  subject: jwt
  issuer: pengzhou
  secretKey: pengzhou2019pwd
  workTime: 3600000
// JwtUtil.java
/**
 * JWT 令牌(token)发放工具
 * @author Somebody
 * @date 2019/8/13 15:35
 */
@Data
@Component
@ConfigurationProperties(prefix = "jwt-util")
public class JwtUtil {
    private String subject;
    private String issuer;
    private String secretKey;
    private Long workTime;

    public String createJwtToken(String username){
        SignatureAlgorithm signatureAlgorithm1 = SignatureAlgorithm.HS256;
        Date now = new Date();
        Long nowDate = now.getTime();

        // 构造token的头部信息(Header)
        Map<String,Object> tokenHeader = new HashMap<>();
        tokenHeader.put("alg",signatureAlgorithm1.getValue());
        tokenHeader.put("typ", "JWT");

        // 构造payload和Signature
        JwtBuilder builder = Jwts.builder().setHeader(tokenHeader)
                .claim("username",username)
                .setSubject(subject)
                .setIssuer(issuer)
                .setIssuedAt(now)
                .setExpiration(new Date(nowDate+workTime))
                .signWith(signatureAlgorithm1,secretKey);

        return builder.compact();
    }

    public Claims parseToken(String token){
        Jws<Claims> jws = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token);
        return jws.getBody();
    }
}
2.Vue.js相关
  • javascript -ES6
// ES6 导入 和 导出
// ES6 语法在webpack打包时需要使用babel-core babel-load等相关组件进行转化
import 模块名 form '模块标识符'
export default{
...
}export 暴露成员
export const model = () => {
...
}

// Node 导入 和 导出
var 名称 = require('模块标识符')
module.exports 和 export 暴露成员
  • 孤儿语法的使用
// 正常版
import App from './App.vue'
new Vue({
	el: 'app',
	render: function (createElements){
	// createElements 是一个方法,调用它可以把指定的组件模板渲染为html结构
	return createElements(App);
	}
})
// ES6孤儿进化版
import App from './App.vue'
new Vue({
	el: 'app',
	render: c => c(App)
})
  • Element-ui 表单验证
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <el-form-item label="密码" prop="pass">
    <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="确认密码" prop="checkPass">
    <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="年龄" prop="age">
    <el-input v-model.number="ruleForm.age"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>
<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('年龄不能为空'));
        }
        setTimeout(() => {
          if (!Number.isInteger(value)) {
            callback(new Error('请输入数字值'));
          } else {
            if (value < 18) {
              callback(new Error('必须年满18岁'));
            } else {
              callback();
            }
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ],
          age: [
            { validator: checkAge, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

利用rules来做验证,rules中也可以写正则表达式。

data(){
    return {
      dialogRules: {
        loseEfficacyReason: [
          { required: true, message: '请输入原因', trigger: 'blur' },
          { min: 2, message: '请输入不少于2个字符', trigger: 'blur' },
          { pattern: /^[A-Za-z0-9\u4e00-\u9fa5]+$/, message: '不允许输入空格等特殊符号' }
        ]
      }
    }
}
3.原型设计相关
  • 重点要求
    对需求的分析考虑要非常全面!
  • 工具
    Balsamiq Mockups 3
  • 注意点
  1. 一致性要求,包括内容、位置、对齐方式:
    表格中通常文字左对齐,数字右对齐;
    确认框,取消在左边,确定在右边;
  2. 网页的左右留白;
  3. 原型设计时,需要结合好数据字段,要将字段全部展现出来,不能省略;
  4. 吐槽一句:我点点点NM的整个网页~

解决方案

1. sql语句like字段参数带有“%_”保留关键字符的问题
  • 问题起因:
# 例:
Select * From User Where username Like Concat("%", :username, "%");

:username为用户输入参数,当用户输入%或_时,sql会将%或_当作保留字,%匹配任意字符,_则为单个字符占位符,最终导致查询结果不是设想的结果。

  • 解决方案:
    sql在语句层面提供了解决方案,即是利用escape来自定义转译符号,但要注意的是escape只能在like子句中起作用。
Select * From User Where username Like "%/%/_%" escape "/";

上面这句sql的最终效果就是查找 username中包含 “%_” 这一字符串的用户信息,另外有多个like字句时,需要多次写escape。

 Select *From User Where username Like "%/%/_%" escape "/" or email Like "%/_ty%" escape "/";
2. 字符串正则匹配并插入字符的问题
  • 问题起因:
    针对上一个问题,需要对拼接入sql语句like字段的参数进行处理,在参数中的%和_符号前添加“/”转义符。即对字符串进行查询替换,这里有两个解决方案:
  • 解决方案:
// 方法一:
public static void main(String[] args) {
	String usernameLike = "%ad%_asd%";
	usernameLike.replaceAll("%","/").replaceAll("_","/");
}
// 方法二:
public static void main(String[] args) {
	StringBuilder usernameLike = new StringBuilder("%ad%_asd%");
	Pattern pattern = Pattern.compile("[_%]");
	Matcher matcher = pattern.matcher(usernameLike);
	Stack<Integer> indexSk = new Stack<>();
	while(matcher.find()) {
	    indexSk.push(matcher.start());
	}
	while(!indexSk.empty()){
	    usernameLike.insert(indexSk.pop(),"/");
	}
}

需要在代码简洁性和性能上做一个取舍。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值