项目实战

  • 功能性
    • 登陆流程
    • 验证码
  • JavaWeb
    • Service、Dao 方法名规范
    • form 文件上传 - 前端、后台、实时预览
    • 页面可见性
    • Service 层
    • 面向接口编程
  • 后端技巧
    • 利用 Jackson 将 Java 对象转成 Json 字符串
    • 利用反射获取泛型的类型
  • 前端技巧
    • 利用 reset 清空 form 表单
    • 图片的 MIMEType
    • 验证码功能发送不同的参数防止缓存
    • 登陆/修改密码功能,利用隐藏域发送加密后的密码

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

项目 Gitee 地址:https://gitee.com/szluyu99/xmg-resume

功能性

登陆流程


JS 的 MD5 库:https://blueimp.github.io/JavaScript-MD5/

MD5 在线生成:https://www.cmd5.com/

验证码

验证码 (CAPTCHA),可以用于防止大规模注册、暴力破解密码、刷票、论坛灌水等

  • Completely Automated Public Turing test to tell Computers and Humans Apart 的缩写
  • 全自动区分计算机和人类的图灵测试

传统的验证码:由扭曲倾斜的文字、干扰线组成

  • 由服务器端生成验证码图片,返回给客户端展示

在 Java 中,可以使用 Kaptcha 库生成验证码

Kaptcha 产自 Google

常用的配置有:字体、内容的范围、尺寸、边框、干扰线、样式等

<dependency><groupId>com.github.penggle</groupId><artificatId>kaptcha</artificatId><version>2.3.2</version>
</dependency>

JavaWeb

Service、Dao 方法名规范

  • 获取单个对象的方法用 get 做前缀
  • 获取多个对象的方法用 list 做前缀
  • 获取统计值的方法用 count 做前缀
  • 插入的方法用 save(推荐)或 insert 做前缀
  • 删除的方法用 remove(推荐)或 delete 做前缀
  • 修改的方法用 update 做前缀

form 文件上传 - 前端、后台、实时预览

form 如果要支持文件上传,必须设置 2 个属性:

  • method="post"
  • enctype="multipart/form-data"
    一旦 form 设置了这一项,Java 后台就无法通过 request.getParameter 获取参数

Java 后台中常用 commons-fileupload 来接收客户端上传的文件

  • 解析 request 为 List<FilteItem>
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
List<FileItem> items = upload.parseRequest(request);
for (FilteItem item : items) {if (item.isFormField()) { // 非文件} else { // 文件}
}
  • 解决中文文件名乱码问题
upload.setHeaderEncoding("UTF-8");

刚上传完毕的图片,有可能会出现无法实时预览的问题(要等一会才能预览成功)

想要实现实时预览,把 Tomcat 的缓存资源功能关掉即可,在 %TOMCAT_HOME%/conf/context.xml 中增加 Resources 标签:

<?xml version="1.0" encoding="UTF-8"?>
<Context><WatchedResource>WEB-INF/web.xml</WatchedResource><WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource><WatchedResource>${catalina.base}/conf/web.xml</WatchedResource><Resources cachingAllowed="false" cacheMaxSize="0" />
</Context>

页面可见性

正常不应该可以直接访问 xx.jsp 页面,因为这是静态页面,必须通过 Servlet 转发访问才能访问到有数据的页面。

为了防止 .jsp 文件被访问到,可以将其放置到 WEB-INF 文件夹下

网页中的静态资源(.css、img 等)一般是可以直接访问到的,因此可以不用放到 WEB-INF 中

Service 层

  • Servlet:控制器层
  • Service:业务层,用来完成具体的业务
  • Dao:数据访问层

Service 层存在的原因是:有时候某个业务可能会多次调用数据库相关的操作,在项目很简单的情况下(Service 层所做的事情就是直接调用 Dao 层),Service 存在的意义不明显,但是当项目变大以后,Service 所处理的一些业务操作就需要抽取出来比较清晰。

面向接口编程

为什么需要面向接口编程?

  • 接口只是定义了一种规范,比如 Dao 接口规定了访问数据库有哪些操作,具体具体如何实现这些操作是不固定的,例如使用 Hibernate、Mybatis、Spring-JDBC 等,如果没有接口的约束,当切换了数据库的实现方案后需要改变大量的代码;但是如果有接口的约束,只需要去实现各个方案对数据库的具体操作即可。

后端技巧

利用 Jackson 将 Java 对象转成 Json 字符串

Person person = new Person(1, "张三", 12);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(person);
// {"id":"1", "name":"张三", "age":"12"}

利用反射获取泛型的类型

使用场景是自动生成表名,根据泛型的类型获取类名,然后转为数据库的表名

public class Student extends Person<String, Integer>
implements Test1<Integer, Double>, Test2<Double, Long, StringBuilder> {// 获取泛型的类型public void printGenericType() {// 父类ParameterizedType superClassType  = (ParameterizedType) getClass().getGenericSuperclass();Type[] args = superClassType.getActualTypeArguments();for (Type arg : args) {System.out.println(arg);}System.out.println("-----------------------------");// 接口Type[] interfaceTypes = (Type[]) getClass().getGenericInterfaces();for (Type type : interfaceTypes) {ParameterizedType interfaceType = (ParameterizedType) type;Type[] interfaceArgs = interfaceType.getActualTypeArguments();for (Type arg : interfaceArgs) {System.out.println(arg);}}}
}
java.lang.String
java.lang.Integer
-----------------------------
java.lang.Integer
java.lang.Double
java.lang.Double
java.lang.Long
java.lang.StringBuilder

大驼峰 (MyAge)小驼峰 (myAge) 转为 下划线(my_age)

/*** 将大驼峰(MyAge)、小驼峰(myAge) 转为 下划线(my_age)**/
public static String underlineCased(String str) {if (str == null) return null;int len = str.length();if (len == 0) return str;StringBuilder sb = new StringBuilder();sb.append(Character.toLowerCase(str.charAt(0)));for (int i = 1; i < len; i++) {char c = str.charAt(i);if (Character.isUpperCase(c)) {sb.append("_");sb.append(Character.toLowerCase(c));} else {sb.append(c);}}return sb.toString();
}

前端技巧

利用 reset 清空 form 表单

jQuery 获取的并不是原生的 DOM 对象,通过 jQuery 拿到表单无法调用 reset,需要转成原生 DOM:

document.querySelector('#add-form-box form').reset() // 原生的表单DOM对象有reset方法
// $('#add-form-box form').reset() // 报错,jQuery获取的不是原生DOM,没有reset方法
$('#add-form-box form')[0].reset()

注意:调用 reset 方法不会重置 type="hidden" 的 input 输入框,需要使用 js 单独处理

图片的 MIMEType

选择文件的 input 可以通过 accept 来控制接收的文件类型,image/* 即所有图片类型

<input type="file" name="image" accept="image/*" />

验证码功能发送不同的参数防止缓存

点击验证码应当会刷新图片,但是如果每次请求的地址是相同的,那么浏览器会从缓存中取而不会实现刷新,通过在后面拼接一些不同的参数使得每次发送的请求不同。

$("#captcha").click(function() {$(this).attr('src', '${ctx}/user/catcha?time=' + new Date().getTime())
})

登陆/修改密码功能,利用隐藏域发送加密后的密码

一般不会给输入的新密码的 input 添加 name 使得用户输入的密码直接发送到服务器,而是在前端对用户输入的密码进行一个加密,将加密后的值设置到隐藏域<input type="hidden" name="newPassword" />",通过隐藏域发送加密后的密码。

<!-- 隐藏域用于发送加密后的密码 -->
<input type="hidden" name="password" />
<!-- 用户输入的ipnut不设置name则不会发送 -->
请输入密码:<input type="password" id='password' />
$('[name=password]').val(md5($('#password').val()))

有些网址在输入完密码点击登陆后,密码栏的字符会突然变多,实际上这就是进行了加密再发送,采用上面的方法可以避免点击登陆后密码栏字符变多的情况

【Java从0到架构师】个人简历项目实战相关推荐

  1. 【Java从0到架构师(1),Java中高级面试题总结(全面)

    JSP 九大内置对象 MySQL 基础 + 多表查询 [Java从0到架构师]MySQL 基础 MySQL MySQL 的使用步骤 数据库的内部存储细节 GUI 工具 SQL 语句 DDL 语句 DD ...

  2. 【Java从0到架构师】项目实战 - 驾考(旧)- Freemarker、MyBatis-Plus

    项目实战 - 驾考(旧)- Freemarker.MyBatis-Plus 各种 Object Freemarker 简单使用 常用功能 集成到 SpringBoot MyBatis-Plus 简单使 ...

  3. 【Java从0到架构师】SpringCloud - Sleuth、Zipkin、Config

    SpringCloud 链路追踪组件 Sleuth Zipkin 分布式配置中心 - Config Git + Config 分布式配置中心 Java 从 0 到架构师目录:[Java从0到架构师]学 ...

  4. 【Java从0到架构师】SpringCloud - Hystrix、Zuul

    SpringCloud 基本概念 熔断和降级 服务雪崩效应 服务熔断与降级 - Hystrix SpringBoot 集成 Hystrix 熔断降级服务异常报警通知 重点属性 - 熔断隔离策略.超时时 ...

  5. 【Java从0到架构师】SpringCloud - Eureka、Ribbon、Feign

    SpringCloud 分布式.微服务相关概念 微服务框架构选型 SpringCloud 概述 服务注册与发现 - Eureka 案例项目 Eureka 自我保护机制 微服务调用方式 - Ribbon ...

  6. 【Java从0到架构师】RocketMQ 使用 - 集成 SpringBoot

    RocketMQ 消息中间件 集成 SpringBoot 入门案例 生产消息类型 - 同步.异步.一次性 消费模式 - 集群.广播 延时消息 设置消息标签 设置消息的 Key 自定义属性设置 消息过滤 ...

  7. 【Java从0到架构师】RocketMQ 使用 - 发送消息、接收消息、特殊消息

    RocketMQ 消息中间件 入门案例 NameServer 地址 发送消息 同步发送消息 异步发送消息 一次性发送消息 生产者组.消息封装 接收消息 消费方式:推式消费.拉式消费 消息方式:集群模式 ...

  8. 【Java从0到架构师】RocketMQ 基础 - 应用、核心组件、安装

    RocketMQ 消息中间件 基础知识 消息中间件的应用 异步解耦 削峰填谷 消息分发 RocketMQ 核心组件 RocketMQ 安装 源码安装 修改配置参数 启动 管理控制台安装 测试项目 Ja ...

  9. 【Java从0到架构师】Dubbo 基础 - 设置启动时检查、直接提供者、线程模型、负载均衡、集群容错、服务降级

    Dubbo 分布式 RPC 分布式核心基础 分布式概述 RPC Dubbo Dubbo 入门程序 - XML.注解 部署管理控制台 Dubbo Admin 修改绑定的注册 IP 地址 设置启动时检查 ...

最新文章

  1. LED液晶与OLED:电视显示技术比较
  2. 图解 Git 工作原理
  3. 利用gearman实现redis缓存mysql
  4. 永远不要在Linux执行的10个最危险的命令
  5. “你不明白欣德利 - 米尔纳的哪一部分?”
  6. 汇编 CALL和RET指令
  7. [转载]C#流,字节数组,字符串
  8. oracle 把逗号分隔符,将逗号分隔为Oracle中的列
  9. 前端框架:执行流程分析之路由与菜单
  10. 去大厂也就图一乐,真人上人还得是外包
  11. 传统的主从复制的概念和要点
  12. dom元素滚动条高度 js_javascript 设置元素滚动大小
  13. python 多线程笔记(2)-- 锁
  14. C++基础——非类型模板参数
  15. phpPgAdmin-5.1安装配置
  16. ARM64移动处理器解惑
  17. 管理工作时间的软件有哪些?
  18. 第四篇--关于device
  19. Update Strategy小记
  20. C#中{0}表示什么意思?

热门文章

  1. 监视器(monitor)
  2. Facts have proved that this is more popular than his article
  3. 改进后的新String类
  4. 索引sql server_维护SQL Server索引
  5. sql limit 子句_SQL Order by子句概述
  6. sql用于字符串的聚合函数_SQL字符串函数用于数据整理(争用)
  7. sql安装弹出sqlcmd_SQL Server中SQLCMD实用工具概述
  8. as5 samba 图形配置
  9. eclipse工具中使用Data Source Explorer连接数据库(MySQL)
  10. [源码和文档分享]基于C++的一元多项式的计算