-
课堂笔记:
3.8 用户模型管理--getotp页面实现(16:00) 1. 完成 getotp.html 页面样式的编写。 2. 完成 button 提交业务的编写 先实现页面交互,再实现页面美化。 a. 引入 jquery.js b. 编写 js 代码,实现 button 的 click 事件,用于向后端发送获取短信验证码的请求。 // 绑定 otp 的 click 事件用于向后端发送获取短信验证码的请求 // 使用 ajax 方式发送异步请求完成业务。 // 为 Controller 中的 @RequestMapper 添加指定的 method,consumes(将其声明到控制层基类中) // 注意判空处理 // 注意 button 自定义 click 方法后,该方法内应该返回 false,因为使用 ajax 发送请求处理业务,不需要常见的事件冒泡给 form 提交 POST 方法。 // 注意程序中已经进行了统一异常处理,因此会尽可能返回了 success HTTPstatus = 200 c. 因为是从本地 html 中发送请求到 localhost 的 url 因此会出现跨域安全异常,虽然请求能够到达控制层,并成功被控制层方法处理业务并返回,但是 ajax 请求会认为该请求是不安全的,因此走不到 success 块中,并会给浏览器报错。 在 springboot 中处理 ajax 跨域请求的方式:只要让 response 时刻返回 'Access-Control-Allow-Origin' 为所有的域,即 * 即可。 SpringBoot 提供给我们一个简单注解方式 @CrossOrigin 实现所有 SpringBoot 中所有请求返回对象带上一个 Access-Control-Allow-Origin 标签,即可实现跨域处理。 @CrossOrigin 可使用在 controller 上,或方法级别上,也可以同时使用,Spring将合并两个注释属性以创建合并的CORS配置。 该注解可以有2个参数: origins :允许可访问的域列表 maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。 3. Ajax跨域请求问题,设置一下属性就可以了, 前端 Ajax 请求中添加 xhrFields: {withCredentials: true}, 后端 controller 层添加 @CrossOrigin(origins = "*", allowCredentials = "true") 就可以访问了
查看全部 -
3.5 定义通用的返回对象-异常处理02 1. 为 handlerException() 方法继续添加 @ResponseBody 注解即可将返回的 object 返回给前端页面。 该方式会将异常的所有栈信息序列化后输出到前端页面,因此还需要继续处理,只将前端需要的异常信息返回给前端。 2. 将 ex 强转为 BusinessException ,然后使用其 getErrCode、getErrMsg 方法获取前端需要的异常信息,将其封装为 Map 后封装到 CommonReturnType 对象中,然后再返回给前端。 3. 优化:使用 CommonReturnType 的静态方法 create 构造对象并返回。 4. 继续完善该方法。 判断 exception 是否为 BusinessException 类型,如果不是则为 CommonReturnType 对象赋值 errCode 为 EmBusinessError 枚举中的 UNKNOWN_ERROR 的 code 和 msg。 5. 继续优化异常处理。 因为该处理方式是所有 controller 都需要的方式,因此将其抽象为 BaseController 中的方法,然后让其他 controller 组件去继承该 controller。 6. 总结:a. 定义一个 CommonReturnType, 能够用对应的 status, object 的方式返回所有的被 JSON 序列化对象,供前端解析使用,摒弃掉了使用 httpstatuscode + 内线 tomcat 自带的 error 页面方式去处理响应数据以及异常。 b. 并且定义了一个 BusinessException ,统一管理我们自定义的错误码。 c. 然后,在 BaseController 中定义一个所有 Controller 的基类,使用其中注解了 @ExceptionHandler 的方法来处理所有被 Controller 层捕获的异常。 按照异常的种类由2种处理方式,一种是自定义 BusinessException, 其中有自定义的 error 的 code 和 msg,一种是未知的异常,采用统一处理方式。 d. 异常处理方法上还可以添加日志相关组件,方便项目运行记录与错误排查。
查看全部 -
跨域问题。数据库id没自增。
<insert id="insertSelective" parameterType="com.miaoshaproject.dataobject.UserDO" keyProperty="id" useGeneratedKeys="true"> 为telphone加索引解决重复注册问题
查看全部 -
传统通过手机号注册的流程:
获取用户的otp(需要按照一定的规则生成otp验证码)2.
将otp验证码同对应用户的手机号关联
将otp验证码通过短信通道发送给用户
通过spring包装的httpservletrequest他的本质是一个?。内部拥有threadlocal方式的map, //去让用户在每个线程中,处理自己对应的request,并且有threadlocal清除的机制
查看全部 -
返回的data返回的是exception异常类的反序列化json,强转成BusinessException
//定义exceptionhandler解决未被controller层吸收的exception异常 @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.OK) @ResponseBody public Object handlerException(HttpServletRequest request, Exception ex){ Map<String, Object> responseData = new HashMap<>(); if(ex instanceof BusinessException){ BusinessException businessException = (BusinessException)ex; responseData.put("errCode", businessException.getErrorCode()); responseData.put("errMsg", businessException.getErrMsg()); }else { responseData.put("errCode", EmBusinessError.UNKONW_ERROR.getErrorCode()); responseData.put("errMsg", EmBusinessError.UNKONW_ERROR.getErrMsg()); } return CommonReturnType.create(responseData, "fail"); }
首先定义一个commonReturnType,能够用status和data返回所有json序列化方式的所有的固定的对象,供前端解析使用。摒弃tomca和http自带err页处理。定义common的BusinessErr方式统一管理想要的错误码。然后在baseController中定义通用exceptionhandler类解决未被controller层吸收的exception,并且使用errcode和errmsg统一的方式吃掉了所有内部不可预知的异常
查看全部 -
枚举可以有属性,是个类。定义全局错误码。分布式开发时需要通用的文件做状态码管理。构造函数中super()就是继承的类自身会有初始化机制。
BusinessException和EmBussinessError都共同继承CommonError对应的方法。外界不管是从BusinessException还是EmBussinessError都可以有state和message的组装定义。并且需要共同实现setErrMsg方法,可以用于将原本em中定义的message覆盖掉。
查看全部 -
不能明确地提示用户“手机号不存在”,否则可能会受到异常攻击。
查看全部 -
使用jQuery处理页面交互,ajax处理请求。
springboot解决跨域问题,添加@CrossOrigin。
查看全部 -
装饰者模式 ,可以使用BusinessException类中的setErrMsg方法将Enum类型的EmBusinessError类中定义的errMsg覆盖掉。
查看全部 -
CrossOrigin
是spring4.2之后才支持的注解
之前都是过滤器处理,很恶心的
查看全部 -
落单减库存实现:
amount:数量 stock:库存
update item_stock set stock = stock - #{amount}
where item_id = #{itemId} and stock >= #{amount}
查看全部 -
之前一直报错
Unknown system variable 'query_cache_size'
查了下说是mysql connector驱动版本问题,改成了8.0.11
依然没有解决,查询后发现是驱动的名称也需要改
driver-class-name: com.mysql.cj.jdbc.Driver mysql8的版本 com.mysql.jdbc.Driver 旧版本
而后又报错
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
大概是时区的问题,在连接字符串后加上?serverTimezone=UTC
终于不报错了,有相同情况的同学可以参考,这是我的mybatis-generator
<?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> <classPathEntry location="C:\Users\99219\.m2\repository\mysql\mysql-connector-java\8.0.11\mysql-connector-java-8.0.11.jar" /> <context id="DB2Tables" targetRuntime="MyBatis3"> <!--数据库链接地址及账号密码--> <jdbcConnection driverClass = "com.mysql.cj.jdbc.Driver" connectionURL = "jdbc:mysql://127.0.0.1:3306/miaosha?serverTimezone=UTC" userId = "root" password = "root"> </jdbcConnection> <javaTypeResolver > <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--生成DataObject类存放位置--> <javaModelGenerator targetPackage="com.miaoshaproject.dataobject" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!--生成映射文件存放位置--> <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!--生成Dao类的存放位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.miaoshaproject.dao" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!--生成对应表及类名--> <table tableName="user_info" domainObjectName="UserDO"></table> <table tableName="user_password" domainObjectName="UserPasswordDO"></table> </context> </generatorConfiguration>
查看全部 -
订单号生成规则:示例16位
前8位时间信息,年月日
中间6位为自增序列
MySQL没有sequence。可以设计一个sequence自增序列表模拟Oracle的sequence。
最后2位为分库分表位
@Transactional(propagation = Propagation.REQUIRES_NEW)的使用。
可以打在私有方法上,但是没有意义。
transactional标签用于将对应包装的bean设置成一个新的代理bean对象供外部使用,就是说外部调用这个proxy bean的公共方法时先会调用开启事务等的切面工作,若设置成私有方法只能类内用this指针调用,这样被调用的bean是其本身,不是proxy对象,因此没有transactional切面的意义。
不应该定义在private方法的切面上,应该将sequence生成定义成单独的service,然后用public方法去做切面,现在的代码实现方式等于是没有用到service生成的切面。
事务嵌套的相关知识,的确同类内方法调用,内层方法是无法实现事务的,因为内层方法是bean本身去调的不是代理对象,所以aop切不进来事务,只能在另外一个类中定义,核心还是要通过动态代理实现事务的切面
查看全部 -
自己做的结构图~~
查看全部 -
我的时间一直显示为null,debug了一下发现我的promoModel上来的时间显示为 2019-03-22T10:00:00.000+08:00 这种格式的。网上找了一个方法转换了一下
/** * 日期格式转换yyyy-MM-dd'T'HH:mm:ss.SSSXXX (yyyy-MM-dd'T'HH:mm:ss.SSSZ) TO yyyy-MM-dd HH:mm:ss * @throws ParseException */ public static String dealDateFormat(String oldDateStr) throws ParseException { //此格式只有 jdk 1.7才支持 yyyy-MM-dd'T'HH:mm:ss.SSSXXX DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); //yyyy-MM-dd'T'HH:mm:ss.SSSZ Date date = df.parse(oldDateStr); SimpleDateFormat df1 = new SimpleDateFormat ("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK); Date date1 = df1.parse(date.toString()); DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return df2.format(date1); }
没有用老师给的方法,还好搞定了。
查看全部
举报