# bugDiary **Repository Path**: studygo/bug-diary ## Basic Information - **Project Name**: bugDiary - **Description**: 日常开发常见/重难点bug记录 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-10-16 - **Last Updated**: 2022-01-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # bugDiary ### 介绍 **日常开发常见/重难点bug记录** --- ##### 1.接口返回Long类型,前端js的Number类型容量不够,导致精度丢失 (@JsonSerialize(using = ToStringSerializer.class)) - 案例: 订单列表查询接口,订单在库中bigint类型长度19位,响应给前端时,前端显示的都是同样的id号. - 造成原因: java中long数据能表示的范围比js中number大,在跟前端交互时,可能造成long类型数据响应到前端js中的number类型变量存储不下 - 处理方式: 在映射的实体类Long类型字段上都加上@JsonSerialize(using = ToStringSerializer.class) 注解; 使用fastjson的ToStringSerializer注解,让系统序列化时,保留相关精度 ``` package com.fasterxml.jackson.databind.annotation; /** * 主键ID */ @JsonSerialize(using = ToStringSerializer.class) private Long orderId; ``` - 补充说明: 关于这个注解的方法,可以自己定义class, 作为using的值来使用. 还可以 using = DateToLongSerializer.class,当转成json时,将Date类型转换为秒Long ``` /** 订单创建时间 */ @JsonSerialize(using = DateToLongSerializer.class) private Date createTime; ``` ##### 2.数据表映射的实体pojo类中,Date类型字段,没有限定时区,查询时反序列化映射的错误的时间.需要在该字段上加注解 @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") - 说明: timezone = "GMT+8"是指定东八区北京时间 ``` @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date createTime; ``` #### 3.过滤器解决跨域问题 - 原doFilter方法: ``` @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 解决跨域 HttpServletResponse response = (HttpServletResponse) servletResponse; HttpServletRequest request = (HttpServletRequest) servletRequest; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "0"); response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, Authorization,DeviceCode"); response.setHeader("Access-Control-Allow-Credentials", "true"); if(request.getMethod().equals("OPTIONS")){ return; } servletResponse.setCharacterEncoding("UTF-8"); Subject subject = parseLoginToken(request,response); String requestsUri = request.getRequestURI(); String ctxPath = request.getContextPath(); String url = requestsUri.substring(ctxPath.length()); if ( notLoginUrls.contains(url) && Objects.isNull(subject) ) { filterChain.doFilter(servletRequest, servletResponse); } else { response.addHeader("Content-Type", "application/json; charset=utf-8"); response.setHeader("Access-Control-Expose-Headers", HERDER_AUTHORIZATION); if (Objects.nonNull(subject)) { servletRequest.setAttribute("username", subject.getUsername()); servletRequest.setAttribute("unionId", subject.getUnionId()); servletRequest.setAttribute("role", subject.getRole()); filterChain.doFilter(servletRequest, servletResponse); return; } try (PrintWriter writer = servletResponse.getWriter()){ RestFullResponse baseResponse = RestFullResponse.fail(RestFullCode.NOT_LOGIN); char[] chars = JSONObject.toJSONString(baseResponse).toCharArray(); writer.write(chars); writer.flush(); } } } ``` - 修正跨域后的doFilter方法 ``` @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 解决跨域 HttpServletResponse response = (HttpServletResponse) servletResponse; HttpServletRequest request = (HttpServletRequest) servletRequest; response.setHeader("Access-control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, Authorization,DeviceCode"); response.setHeader("Access-Control-Allow-Credentials", "true"); if(request.getMethod().equals("OPTIONS")){ response.setStatus(HttpServletResponse.SC_OK); return; } servletResponse.setCharacterEncoding("UTF-8"); Subject subject = parseLoginToken(request,response); String requestsUri = request.getRequestURI(); String ctxPath = request.getContextPath(); String url = requestsUri.substring(ctxPath.length()); if ( notLoginUrls.contains(url) && Objects.isNull(subject) ) { filterChain.doFilter(servletRequest, servletResponse); } else { response.addHeader("Content-Type", "application/json; charset=utf-8"); response.setHeader("Access-Control-Expose-Headers", HERDER_AUTHORIZATION); if (Objects.nonNull(subject)) { servletRequest.setAttribute("username", subject.getUsername()); servletRequest.setAttribute("unionId", subject.getUnionId()); servletRequest.setAttribute("role", subject.getRole()); filterChain.doFilter(servletRequest, servletResponse); return; } try (PrintWriter writer = servletResponse.getWriter()){ RestFullResponse baseResponse = RestFullResponse.fail(RestFullCode.NOT_LOGIN); char[] chars = JSONObject.toJSONString(baseResponse).toCharArray(); writer.write(chars); writer.flush(); } } } ```