今天完成的事情:
完成任务4的深度思考
1.JSP是什么?JSP中可否直接连接数据库?为什么现在不推荐使用%%来写JSP的代码,而是使用C标签?
JSP全称Java Server Pages,是一种动态网页开发技术。 jsp里面包含html代码 和 java代码 。 以jsp后缀为结尾。
如何在jsp中的html中插入jsp代码:通过jsp标签在 HTML网页中插入Java代码。标签通常以<%开头以%>结束。
jsp主要作用: 把Java代码内嵌在JSP页面中,把html的动态数据渲染成静态页面。 Web容器会把jsp转换为一个servlet然后执行。
JSP可以直接连接数据库
参考: https://blog.csdn.net/weixin_42014622/article/details/80691901
推荐C标签:
原因:
%%要自己手动在里面写java代码,增加开发过程,页面复杂,出问题排错也麻烦。
而c标签封装了很多java所需要的实现的功能,使用方便,页面简洁。
jsp内引用c标签的语法
2.Html有哪些常用的标签,CSS有几种引用方式,JS应该在顶部还是应该在底部加载?
html常用标签;
1、标题标签(头部),<title></title>标签,title标签是头部标签。
2、标题标签(体),<h1></h1>,这个标题标签可以从1到6,每一级标签独占一行,且默认有字体大小的显示。
3、水平线标签</hr>,在html中添加一条横线。
4、段落标签<p></p>,将段落文字插入html中。
5、换行标签</br>,实现换行。
6、字体标签<font></font>,中间可以添加文字。
7、加粗标签<b></b>,对内容加粗。
8、斜体标签<i></i>,将内容斜体展示。
css有4种引用方式 分别为:
1.行内样式
指写在标签里的Style元素的值
<p style="color: #FF0000;">行内样式</p>
2.内嵌式
写在HTML页面的head标签里。
<style type="text/css"> </style>
3.链接式
在head标签内部进行,但是需要在外部专门写CSS文件。(我们做task4时使用的就是这种方法 加载的静态css资源)
<link rel="stylesheet" href="css/Demo.css" />
4.导入样式
同样在head标签内。
<style type="text/css">
@import url("css/Demo.css");
</style>
JS应该在顶部还是应该在底部加载?
html文档一般是按顺序执行的,也就是说头部的先执行底部的后执行
css是写样式的,可以放在头部,先把页面样式加载出来,让用户先看到页面。
而js一般是写交互的,可以放到最后执行,以便让用户更快的看到页面,提升用户体验。
3.SEO是什么,后端在用JSP的方式输出页面时,可以做的SEO优化有哪些?
SEO(Search Engine Optimization)——搜索引擎优化。即利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。吸引更多的用户访问网站,提高网站的访问量,提高网站的销售能力和宣传能力,从而提升网站的品牌效应。
jsp可以做的SEO优化
正确设置html中的 title、keywords、description
title
首页title写法,一般是“网站名称-主关键词或一句含有主关键词的描述”。
栏目页title写法,一般有2种:“栏目名称-网站名称”、“栏目名称栏目关键词-网站名称”。
分类列表页title写法,一般是“分类列表页名称-栏目名称-网站名称”
keywords
首页keywords写法,一般是“网站名称,主要栏目名,主要关键词”。
栏目页keywords写法,一般是“栏目名称,栏目关键字,栏目分类列表名称”。
description
首页description写法,一般是将首页的标题、关键词和一些特殊栏目的内容融合到里面,写成简单的介绍。
栏目页description写法,一般是将栏目的标题、关键字、分类列表名称融合到里面,写成简单的介绍。
3个标签按重要性来分:title>description>keywords
4.Tiles现在的版本是多少?Template,Attribute,Definition,ViewPreparer分别是什么?
tiles最新版本是3.0.8 已经停止对这个项目的更新。
模板:Template
在Tiles中,模板(Template)是一个页面的布局部分。里面是一个固定的页面结构。
我的template(home.jsp) 分为三个结构 head body footer
属性:Attribute
属性是模板中的空白,它在你的应用程序中被填充到模板中。
属性可以是以下三种类型:
string:属性是string的话,会将string直接呈现在页面。
template:属性是一个模板(Template),有无属性都行。如果有属性的话,你也要将他们填充后再呈现页面。
definition:它是一个可重复使用组成的页面,包含所有的属性来填充以呈现页面。
定义:definition
定义是呈现给最终用户的组合物;本质上,一个定义是由一个模板和完全或部分填充的属性组成的。
说白了就是:一个定义是由一个模板(public)和属性(body)组成的。
视图助手:View Preparer
有时候一个定义在呈现之前需要“预处理”。例如,显示一个menu时,menu的结构必须被创建并且已经保存在request范围内。
为了达到“预处理 ”,视图助手将会被用到,视图助手将在呈现定义之前被调用,因此在将“定义”呈现所需的东西都会被正确的“预处理 ”。
参考: https://my.oschina.net/jast90/blog/284254?nocache=1495100802130
5.Tiles有什么用处,为什么要用Tiles,如果不使用Tiles,可以实现公共部分的复用吗?
Tiles框架提供了一种模板机制,可以为某一类页面定义一个通用的模板,该模板定义了页面的整体布 局。布局由可以复用的多个块组成,每个页面可以有选择性的重新定义块而达到组件的复用。
个人理解: tiles框架的作用,就是将一个完整的前端html页面拆分成若干jsp页面,固定不变的页面拆分为一部分。经常变化的页面或者需要写活数据的页面拆成另外一部分。再通过tiles框架将所有部分组装起来。从而方便在不同页面内处理动态数据,轻易实现对固定页面的重用,使页面修改维护更简洁。
如果不用tiles框架可以的,还有其它的页面布局工具:
SiteMesh 是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的。
JSP Layout 是一个用来实现 JSP 布局支持的简单示例项目。该项目只需要一个 Servlet 类,一些配置即可
比较:tiles SiteMesh都必须使用预先配置好的布局,使用XML文件来定义布局,真正的数据显示页面无法灵活控制所需的布局;
而 JSP Layout 是一个超轻量级的布局控制,要使用哪个布局文件,由目标页面通过代码进行控制
参考: https://blog.csdn.net/u012492220/article/details/17075379
6. 套页面的前后端协作方式中,怎么传递参数给前端JS?怎么控制页面之间的跳转?
通过绝对路径加上controller的请求路径,进行页面跳转,并传递相关数据。
7.Velocity,Freemark是什么,和JSP的区别在哪里?推荐使用哪种模板语言?
在java领域,表现层技术主要有三种:jsp、freemarker、velocity。
jsp
优点:
1、功能强大,可以写java代码
2、支持jsp标签(jsp tag)
3、支持表达式语言(el)
4、官方标准,用户群广,丰富的第三方jsp标签库
5、性能良好。jsp编译成class文件执行,有很好的性能表现
缺点:
jsp没有明显缺点,非要挑点骨头那就是,由于可以编写java代码,如使用不当容易破坏mvc结构。
velocity是较早出现的用于代替jsp的模板语言
优点:
1、不能编写java代码,可以实现严格的mvc分离
2、性能良好,据说比jsp性能还要好些
3、使用表达式语言,据说jsp的表达式语言就是学velocity的
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多。
3、对jsp标签支持不够好
freemarker
优点:
1、不能编写java代码,可以实现严格的mvc分离
2、性能非常不错
3、对jsp标签支持良好
4、内置大量常用功能,使用非常方便
5、宏定义(类似jsp标签)非常方便
6、使用表达式语言
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多
推荐使用freemarker,原因:
1、性能。velocity应该是最好的,其次是jsp,普通的页面freemarker性能最差(虽然只是几毫秒到十几毫秒的差距)。但是在复杂页面上(包含大量判断、日期金额格式化)的页面上,freemarker的性能比使用tag和el的jsp好。
2、宏定义比jsp tag方便
3、内置大量常用功能。比如html过滤,日期金额格式化等等,使用非常方便
4、支持jsp标签
5、可以实现严格的mvc分离
参考 : https://blog.csdn.net/tjcyjd/article/details/16803877
EL表达式是一种JSP技术,能够代替JSP中原本要用Java语言进行显示的语句,使得代码更容易编写与维护。最基本的语法是${express}。
EL表达式只能读数据,不能修改数据。
常用表达式:
一 获取不同类型的数据并显示
(1)基本数据
${name}
(2)对象数据
${requestScope.name}
(3)list数据
${list_1[1].name }
(4)map数据
${map['1'].name } 是数字的话只能用括号,就算put进去的key值是字符串类型
${map.a.name }
二 运算符
1)语法:${运算表达式}
2)常见运算符:==(eq) !=(ne) <(lt) >(gt) <=(le) >=(ge) &&(and) ||(or) !(not)
3)判断是否为空:${empty name }
4)三目运算符:${name == null?"null":name }
三 获取常用对象
1)语法:${隐式对象名称}
2)隐式对象表


参考: https://blog.csdn.net/zdb292034/article/details/81280182
- 9. C标签又是什么?怎么写一个自定义的标签?自定义的标签通常有什么用处?
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
而c标签属于JSTL功能中的核心标签core。
引入语法:
JSTL 核心标签库(C标签)标签共有14个,功能上分为4类:
(1)表达式控制标签:
(2)流程控制标签:
(3)循环标签:
(4)URL操作标签:
表达式控制标签:
(1)c:out标签:用来显示一个表达式的结果,与<%= %>作用相似,它们的区别就是标签可以直接通过"."操作符来访问属性。
(2)c:set标签:用于设置变量值和对象属性。
(3)c:remove标签:用于移除一个变量,可以指定这个变量的作用域,若未指定,则默认为变量第一次出现的作用域。
(4)c:catch标签:主要用来处理产生错误的异常状况,并且将错误信息储存起来。
流程控制标签:
(1)c:if标签:判断表达式的值,如果表达式的值为 true 则执行其主体内容。
(2)c:choose标签:与Java switch语句的功能一样,用于在众多选项中做出选择。
(3)c:when标签:c:when在c:choose中,就相对于case在switch语句中。
(4)c:otherwise标签:c:otherwise在c:choose中,就相对于default在switch语句中。
循环标签:
(1)c:import标签:提供了所有<jsp:include>行为标签所具有的功能,同时也允许包含绝对URL
(2)c:url标签:将URL格式化为一个字符串,然后存储在一个变量中。
(3)c:redirect标签:通过自动重写URL来将浏览器重定向至一个新的URL,它提供内容相关的URL,并且支持c:param标签。
(4)c:param标签:用于在标签中指定参数,而且与URL编码相关。
自定义标签的编写:(自己写的)
https://blog.csdn.net/qq_42733162/article/details/106045672
自定义标签库的作用:
自定义标签的使用可以使我们避免在JSP中使用JAVA代码。自定义标签就是通过自定义标签实现类来实现复杂的、可重复利用的功能。简化JSP页面,提高代码的复用性。标准标签库JSTL,只能实现基本的标签操作。因此我们可以根据自己的业务需求,制作出复杂的标签,从而加快项目开发。
(就是写一个可实现自定义功能的工具,需要时在jsp页面内直接拿来用)
10.套页面和前后端分离的方式有什么区别,应该在哪种情况下选用哪种解决方式?
套页面是原型还没有做好时,先做一个页面将功能实现,等原型做好后再往上套
前后端不分离
在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高。
这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口。
请求的数据交互如下图:
前后端分离
在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。
在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。
在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。
对应的数据交互如下图 :
任务5看了cookie和session token , des加密 加盐的大概概念
概念比较多,看的有点混乱
简单总结下:
1. cookie就是一小段文本信息,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。
服务器端可以获取修改删除客户端传来的cookie 也可以向客户端返回cookie。
2.session就是储存在服务器上的一个对象,主要用来存储所有访问过该服务端的客户端的用户信息(也可以存储其他信息),从而实现保持用户会话状态
客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
这个图是真的简单明了

3.token
token就是服务器先对用户数据进行加密,生成一个加密字符串token,返还给客户端(客户端通过cookie、sessionStorage、localStorage都可以进行存储,不储存在服务端)
当客户端再次请求服务时, 要带上加密字符串token, 服务器对浏览器传来的token值进行解密,解密完成后进行用户数据的查询,如果查询成功,则通过认证,实现状态保持。

所以,不管是cookie session , token。 他们的作用都是为了保持用户登录状态,从而方便用户在固定时间,对服务器进行相应请求,不用再重复登录。
des加密:
Des是对称加密算法,作用很简单,就是对传入数据库的用户密码进行加密
什么是对称加密: 下图

DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”,是一种使用密钥加密的块算法。
DES 算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是 1972 年美国 IBM 公司研制的对称密码体制加密算法。 明文按 64 位进行分组,密钥长 64 位,密钥事实上是 56 位参与 DES 运算(第8、16、24、32、40、48、56、64 位是校验位, 使得每个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组的加密方法。
基本原理
入口参数有三个:key、data、mode。key 为加密解密使用的密钥,data 为加密 解密的数据,mode 为其工作模式。当模式为加密模式时,明文按照 64 位进行分组,形成明文组,key 用于对数据加密,当模式为解密模式时,key 用于对数据解密。实际运用中,密钥只用到了 64 位中的 56 位,这样才具有高的安全性。
就理解到这么多....剩下的就看不太懂了
加盐的概念:
在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。
密码加密加盐后的改变:
1. 初始密码

2.假设用des对密码加密

3. 如果要加盐 那用户表中多了个字段salt (假设我们用MD5进行加盐---MD5也是一种加密方式)

Salt 可以是任意字母、数字、或是字母或数字的组合,但必须是随机产生的,每个用户的 Salt 都不一样
用户注册的时候,数据库(PwdHash)中存入的不是明文密码,也不是简单的对明文密码进行散列。
而是 MD5( 明文密码 + Salt), 即:
MD5('123' + '1ck12b13k1jmjxrg1h0129h2lj') = '6c22ef52be70e11b6f3bcf0f672c96ce'
还有牵扯到拦截器的概念,感觉更复杂,我还没看。


关于任务1的要求 ,看完概念后对要做什么稍微理解了一些
大概思路就是:
用DES对传入的账号密码参数加密 再用md5加盐
然后再用token把上一步生成的最终密码再加密一遍, 生成加密字符串token
代码中创建一个cookie 放入token
然后客户端再登录时,配置一个拦截器拦截cookie,然后对token进行统一判断有效性。
(如果不拦截的话,只能在controller层中手动创建cookie对象,获取token,再进行token判断,增加代码量还麻烦)
不知道这个思路对不对.....
关于登录的代码 我在任务3中写过一个
逻辑其实也不算难,就是对传入的账号 密码没有进行判空等操作。
//如何登录
@ResponseBody
@RequestMapping(value = "/login",method = RequestMethod.POST)
public Map login(String username,String password) {
Map<String,Object> map = new HashMap<>();
logger.info("输入的用户名为:"+username+",密码为:"+password);
//根据账户名 判断数据库中有无此用户
if (accountService.loginByUser(username)==false){
map.put("msg","用户名不存在,请重新输入!");
map.put("code",201);
return map;
}else{
//根据输入的密码 和通过用户名查询的密码做对比 如果符合 则登录成功
//更改登录状态 跳转到登录成功页面
if (password.equals(accountService.getPassword(username))){
map.put("msg","登录成功");
map.put("'code","200");
return map;
}else{
//如果账户名和密码不符合 跳转回来 重新输入
map.put("msg","密码错误,请重新输入");
map.put("code","201");
return map;
}
}
}
明天计划的事情:
继续进行任务5
完成对cookie的加密加盐 返回token
了解和配置拦截器。
评论