Web正式入门踩坑总结
前言:最近需要跟着老师做一个商业性项目,有关英语学习的网站。因为我是打算从事 Android 方面的工作,其实内心是有些拒绝的,不过在仔细思考和问了一些大佬后决定多学点还是有好处的,毕竟现在大前端的声势如此浩大。而且中途还是可以抽空不断的丰富自己的知识面。(ps : 看了面试题目后觉得面试题还是需要好好看看的。。。)
现在主流的 Web 开发框架应该是 ssm 了吧(ps:这方面我真没注意过,只知道 ssh 确实老了。而各大厂的框架非常多,有错误欢迎指出)。所以在项目正式开始之前老师让我们先把框架搭建起来,之后在搭建好的环境上做一个简单的图书管理系统就表示已经入门了。(其实说实话一开始我的内心是吐槽的,因为感觉从刚上大学开始一直到现在学习入门总是在做图书管理系统,自学习Android 的时候不是,不过后来的课程也是这个,,,无力吐槽)。但是在这过程中发现还是很有必要的,下面我把遇到的一些问题总结给大家。
1 请求的值到底是什么?
在之前没有使用框架的时候我也写过简单的 Web 程序。不过是比较直接的 servlet 结合 HTML 以及 css 和 js 的使用。哪个时候比较注意的地方就是在表单提交的时候 action 后面的值。在经常会出现问题,一开始好好的突然就 404 。后来逐渐把握到了感觉一个是 大小写别写错, 大小写别写错, 大小写别写错;还有一个就是 web.xml 文件别配置错误。确定 ctrl 之后鼠标能够看到超链接的状态。这样如果还出现问题 stop tomcat -> clean -> start 。应该就 OK 了。不过目前来说都是直接使用请求框架。下面来看两个图:
webq01.png第二个:注意黑色字体部分即可
webq02.png大家能不能注意下这两者有没有什么不同。在最终得到的结果中?
答案:我们获取了我们想要的结果又完整的路径和端口号还有项目的上下文环境,所以大功告成了。我把项目中的${pageContext.request.contextPath}都替换成了<%=basePath%>,然后就完全的解决问题了。
首先 ${pageContext.request.contextPath} 用于解决使用相对路径时出现的问题,它的作用是取出所部署项目的名字。
${pageContext.request.contextPath}`等价于`<%=request.getContextPath()%>`或者可以说是`<%=request.getContextPath()%>`的EL版
意思就是取出部署的应用程序名或者是当前的项目名称
比如我的项目名称是SpringMVC 在浏览器中输入为`http://localhost:8080/SpringMVC/login.jsp
${pageContext.request.contextPath}
或<%=request.getContextPath()%>
取出来的就是/SpringMVC,而”/”代表的含义就是http://localhost:8080 。
所以我们项目中应该这样写${pageContext.request.contextPath}/login.jsp说一下亲身的例子大概就明白了。这里我先用的是相对路径,很多种情况下都没出错。
那第二个呢?
作用相当生成了绝对路径:这样的好处在于可以为当前的链接使用绝对路径(同时,也强烈推荐使用绝对路径)
另外,如果页面转向某个Servlet,而Servlet里又是forward到的某个jsp页面,如果这时写相对路径就应该先找到Servlet的路径,也就是web.xml中配置的url-pattern中的路径,如:假设有个x.jsp放在webapplication根目录下,而主页index.jsp是提交到servlet上去的,由Servlet来分发forward到x.jsp,Servlet的url配置如下
`<url-pattern>/servlet/TestServlet</url-pattern>`
那么Servlet完成forward转向后,如果没有<base href="<%=basePath%>">
, x.jsp中
<script type="text/JavaScript" src="script/check.js"></script>
就会失效,因为Servlet的访问路径为<http://localhost/webapp/servlet/TestServlet >那么web服务器会到 http://localhost/webapp/servlet/script/ 下去找check.js此时这里肯定是没有这个文件的,所以,如果遇到这样的情况建议使用绝对路径就不会有错。所以建议使用第二种方式而不是第一种方式。
2 HTML 元素中 id 和 name 的区别
说实话因为我之前真的没有留意过这个东西,之前自己写 web 代码真的是随便写一写。这次因为作为基本入门项目来使用所以调用了 js 和 action 最终在 controller 中进行数据处理的时候我才发现了问题。竟然不知道这有什么区别,有什么作用,所以希望分享给大家我的理解。
对 name 来说作用比较大
用途1: 作为可与服务器交互数据的HTML元素的服务器端的标示,比如input、select、textarea、和button等。我们可以在服务器端根据其Name通过Request.Params取得元素提交的值。
用途2: HTML元素Input type='radio'分组,我们知道radio button控件在同一个分组类,check操作是mutex的,同一时间只能选中一个radio,这个分组就是根据相同的Name属性来实现的。
用途3: 建立页面中的锚点,我们知道link是获得一个页面超级链接,如果不用href属性,而改用Name,如:<a name="PageBottom"></a>,我们就获得了一个页面锚点。
用途4: 作为对象的Identity,如Applet、Object、Embed等元素。比如在Applet对象实例中,我们将使用其Name来引用该对象。
用途5: 在IMG元素和MAP元素之间关联的时候,如果要定义IMG的热点区域,需要使用其属性usemap,使usemap="#name"(被关联的MAP元素的Name)。
用途6: 某些特定元素的属性,如attribute,meta和param。例如为Object定义参数<PARAM NAME = "appletParameter" VALUE = "value">或Meta中<META NAME = "Author" CONTENT = "Dave Raggett">。
至于 id 的作用一般使用在 js 函数调用的时候通过 #id名称 来获取控件或者 document.getElementById("id").value 来取得该 id 控件绑定的值。或者在编写 css 代码的时候需要通过 id 来取得值。虽然一般情况通过 class 就可以搞定。
3 ssm 框架中的 Model 的 addAttribute 和 HttpSession 的 addAttribute 的区别和作用
暂无
4 Dao 层写 xml 的参数的时候 SQL 语句的问题
在编写 sql 语句的时候首先一点是需要注意不能在最后赋值的 = 两端加空格。这样会出现错误,因为我们很多人写代码的习惯就是动不动空格,所以在这里可能会出现问题。
<select id="findUser" parameterType="String" resultType="com.english.po.User">
select *
from sys_user
where user_code = #{usercode}
and user_password =#{password}
and user_state = '1'
</select>
还有一点就是参数的类型不要写错,如果是实体类的类型的话最好把整个包路径写下来,如果是正常的基本类型的话那要确保大小写问题以及不要少写字母。
那如果遇到多参数该怎么解决呢?因为不同的参数是不同的类型
int deleteById(Integer id,String name); ---①
int deleteById(@Param(value=”id”Integer id, @Param
(value=”name”String name)) ;---②
<delete id="deleteById">
DELETE FROM gov_pub_search
WHERE id = #{id,jdbcType=INTEGER}
<if test="name != null" >
,p_name = #{name}
</if>
</delete>
记得不管你有多少个参数,只要参数是基本类型且不统一,那就直接在后面加 jdbcType=类型 即可。切记切记。
5 如何获取后台传递的列表数据长度
可能很多人的想法是这样
${list.size}
或者是这样
${list.length}
答案都不是,其实正确的写法应该是这样:
${list[0].name}
比较常用的标签库(jstl 和 求取长度)
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
6 如何设计一个 js 倒计时(需要显示在屏幕上)
其实这里可以在 W3C 网站上找到灵感,不过因为这里我一开始没有留意,所以也试了好几次才成功。当然相信这个对于熟悉的大佬们来说也不算什么了。。
// 6s 倒计时功能
let time = 6;
let doNotKnowWord = 0; // 一共有多少个单词不认识
function closeWindow(){
window.setTimeout('closeWindow()', 1000);
if(time >= 0){
if(time == 0) {
// 调用显示隐藏函数
nextWord();
//调用生词计数功能
doNotKnowWord++
notKnowWord(doNotKnowWord);
}
document.getElementById("show")
.innerHTML=" <font color=red>" + time + "</font> 秒";
time--;
}
else{
window.opener = null; //关闭窗口时不出现提示窗口
window.close();
}
}
布局
<div id="show" class="reduce-time-style">
</div>
不要忘记调用该函数即可。顺便一提,使用 setTimeout() 的时候可以把 window 去掉直接使用 。
7 如何获取传递列表的某个值
说实话这个点困扰了我很长时间,不是困扰在怎么得到,而是知道了怎么得到之后不知道问题出现在哪里,,,稍后我会把代码和截图给出,还望各位老哥知道的多多指教。
${list[0].e_spell}
如上图即可得到列表第一个对象的 e_spell 值。
action01.png这是我的数据库表结构。
先看布局部分:
action02.png然后看 js 代码部分:
action03.png运行这个代码不会出错,但是获取不到 count 下标对应的值,,,说实话这点让我很是无奈。但是如果像下面的写法就可以取得值且没有其他问题:
action04.png大家注意,我把 count 写为了 1 ,事实上我把这个数换成任何正确的下标都可以,只有写 count 变量不行,不过我的目的是为了动态取值而不是只要某一个值,所以这个问题我到写这篇总结的时候还没有明白,希望知道的老哥能够多多指教,谢谢。
ps:console.log 的打印都能在控制台看到没有问题。
8 如何给 div 布局的四周设置阴影部分
相信大家都看到过一个布局,四周加上阴影之后会有一种 3D 独立漂浮的感觉,对于界面显示会更加的友好,越发感觉开发和人生一样,就是不断的遇到问题解决问题。。
老规矩先看布局
action05.png再看样式
action06.png最终毫无疑问就是运行的结果啦
action07.png怎么样,感觉还阔以吧。
9 注意 js 的使用 $ {} 表达式的格式
为什么我要提这一点呢,如果你看了我上面的内容应该注意到我遇到了动态获取列表每一个值的问题,我一开始不知道怎么解决,所以就使用拼接字符串的方法:
document.getElementById('test-word')
.innerText = "${repeatWord[1].e_spell}";
还有这样
let count = 1
document.getElementById('test-word')
.innerText = "${repeatWord[" + count + "].e_spell}";
这样
let count = 1
document.getElementById('test-word')
.innerText = "${repeatWord[" + 'count' + "].e_spell}";
基本能想到的字符拼接我都试了,怀疑人生,我自己都怀疑我写了这么久的字符串链接是不是错的,,,因为它总是说无法识别,格式不正确。。。相信广大程序猿们应该能理解我的感觉
最后我在群里才知道原来 js 的专用格式是 `` 包裹下才可以。什么,你不知道这是什么鬼,没关系,我来和你说,其实他就是英文输入法下 esc 键下的按钮。。。。 好熟悉的字眼,我昨天查怎么在简书里写代码块的时候才知道简书写代码需要三点,哪三点呢?
就是 ```; 结束,惊不惊喜,意不意外?当然有始有终,别忘了在代码最后也要加上这三点。
总结:没有什么事情是简单的,随着大四的到来,周围很多同学说学习这个没什么用,学习那个没什么用,我都不想反驳。学不学是你的事情,能不能用到看老天安排。愿我们成为真实的自己。
网友评论