java EE学习

【【tomcat安装与使用、eclipse的配置】】
1、安装,下载解压版,放到文件夹中即可,点击bin文件夹下的startup即可使用。
2、必须jdk、tomcat配置相关的环境变量,具体见:http://bijian1013.iteye.com/blog/2296682
3、调试手段:
3.1、直接拖动startup.bat到cmd窗口执行,可以见到粗略的调试文字。
3.1、cmd 窗口下将目录移动到软件根目录的bin文件夹下,执行catalina debug,然后执行run,可以看到详细的调试文字。
4、访问tomcat 浏览器输入网址 127.0.0.1:8080 ,即本机地址+端口号即可。
5、发布项目 将html项目文件夹放到webapps下,在4的地址后面加入具体的html路径即可,如:http://127.0.0.1:8080/bootstrap/index.html
6、eclipse配置:在控制台的servers下点击添加,根据提示选择已经安装好的tongmcat即可,注意安装完之后,需要右键open选择severlocations的第二个,user tomcat installation。

【【sevlet】】
sever applet 服务器小程序的组合词。
定义了一系列java类被web服务器识别的规则。
1、file> new> Other> Web> Dynamic Web Project;Dynamic web module version=2.5;finish;
2、在java Resources下的SRC下创建class,继承HTTPsevlet,即可使用sevlet的一些方法。或者实现servlet接口,自己实现里面的init、servletconfig getservletconfig()、service(servletrequest,sevletresponse)、getservletinfo(),destroy。五个方法。
3、httpservlet常用方法有doGet(HttpServletRequest req, HttpServletResponse resp);doPost(HttpServletRequest req, HttpServletResponse resp)两个。父类的五个方法当然也存在。
4、配置xml信息(webapp/web-info/web.xml):

<servlet>
<servlet-name> HelloWeb</servlet-name>
<servlet-class> helloweb.HelloWeb</servlet-class>

</servlet>
<servlet-mapping>
<servlet-name> HelloWeb</servlet-name>
<url-pattern> /HelloWeb</url-pattern>
</servlet-mapping>
这一步如果使用注解方法,直接在servlet类名上注解webservlet("/HelloWeb")也可以实现,前提是类是自己写的而不是jar包提供的。一个servlet可以定义多个访问路径,webservlet({"/x","/",".jsp"})
servlet 是java文件信息,name是自定义的,class是class文件的全路径,即包名+类名。
servlet-mapping 是java文件和html访问路径的映射,url-pattern以“/”开头,表示url所在工程的根目录,后面可以跟具体路径。
另外,sevlet中还可以有其他配置信息:
<load-on-startup> n</load-on-startup> 表示服务器开启时sevlet随即初始化,n是正整数,越小初始化越靠前,相等则由调用的容器自己决定先后。因为容器默认已使用0、1,所以最好从2开始。为负数时,表示不随容器启动。
初始化参数:
<init-param>
<param-name> name</param-name>
<param-value> 11</param-value>
</init-param>
时候初始化的参数后,可以通过sevlet的 getServletConfig()方法获取配置的初始化参数,类似于給session插入值,取值。

【生命周期】
1、inti方法在servlet被创建时执行,只会执行一次。通常是用户对此访问此servlet时,如果web.xml配置了<load-on-startup> 的话,会在服务器开启时初始化执行。
2、destroy在它被销毁时执行,通常是服务器正常关闭时执行。
3、显然,一个servlet是一个单例对象。是线程不安全的。尽量不要使用成员变量操作共同资源。

【请求和相应数据】
1、http请求数据解释:
请求行:post /url http/1.1 表示提交方式,提交地址,http协议版本 浏览器的抓包一般只能抓到请求头和请求体的参数列表,一般不包含请求行。
请求头:
/Accept:application/json, text/javascript, / 可支持的返回文本数据类型,/表示任意类型的数据。
/Accept-Encoding:gzip, deflate 压缩的算法
/Accept-Language:zh-CN,zh;q=0.8 支持的语言
/Cache-Control:no-cache 缓存的操作,此时表示越过缓存直接向服务器请求新的数据。
/Connection:keep-alive 连接方式,此时表示的是保持连接。
/Content-Length:0 post提交数据的字符长度
/Content-Type:application/x-www-form-urlencoded 提交数据的文本类型,此时表示的是经过urlencoding编码的form表单数据。
/Cookie:sessionid=6921d4234bf8884fb46c94e0c3abf719 缓存的cookie
Host:211.147.212.215:5673
Origin:http://211.147.212.215:5673
Pragma:no-cache
/Referer:http://211.147.212.215:5673/iclock/staff/ 提交的全路径
/User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36 来访的浏览器相关信息,包括pc信息,浏览器信息等。
X-Requested-With:XMLHttpRequest
请求体:UserID__id__exact:1616 键值对方式保存的表单信息,一般用key1=value1&key2=value2表示
2.http响应数据解释:
响应行:http/1.1 200 ok 协议版本,返回状态码(200正常处理,404找不到资源;403拒绝访问;500服务器异常) ,状态码的解释文字
响应头:
Cache-Control:no-store
Content-Language:zh-cn 返回的语言
Content-Length:1860 返回的数据长度
Content-Type:text/javascript 返回的数据文本类型
Date:Mon, 24 Sep 2018 09:15:41 GMT 返回数据的日期
Pragma:no-cache
Server:
***************************** 服务器是哪一种类型
Vary:Accept-Language, Cookie
响应体:具体的返回文件,可以是html文件页,也可以是json文件的对象数组。

【rquest对象】
1、浏览器通过get或post方法访问时(路径为tomcat路径+项目名+url-pattern),容器(tomcat)会调用相应的post或get方法。可以通过方法内传递的rekuest/response参数进行开发。
2、简单的开发,取得提交的表单参数:
取得参数:
StringBuffer str=new StringBuffer("<p> “);
Map<String, String[]> para = req.getParameterMap();
for(Map.Entry<String, String[]> entry : para.entrySet()) {
for (String paravalue : entry.getValue()) {
str.append(“paraname=”+entry.getKey() +” |paravalue="+paravalue +"<br/> ");
}

	}
	str.append("&lt;/p&gt; ");

取得参数常用的方法有:
String getParameter(String name) 返回参数列表中匹配的第一个参数值。若该参数不存在,则返回一个空值。
String[] getParameterValues(String name) 返回匹配的参数值数组,若该参数不存在,则返回一个空值。如果只有一个值,数组长度1。
Enumeration getParameterNames 返回所有参数名的enumeration,不存在返回空。该方法已被getParameterMap取代。
map getParameterMap();返回所有参数的map集合。
String getHeader(String name) 返回指定的作为字符串请求消息头的值
Enumeration getHeaderNames() 返回所有消息头的参数名
Enumeration getHeaders(String name) 返回所有消息头的参数值
3、可以使用以下方法給一个request对象中设置一些域对象属性。在转发后进行消息传递。
setAttribute(string name,object obj)
getAttribute(string name)
removeAttribute(string name)
4、转发和重定向:
1、request.getRequestDispatcher(“login_success.html”).forward(request, response);将请求和响应对象传递给下一个sevlet或jsp进行处理,这种方式被称为请求的转发。效果和请求的重定向很相似,但浏览器内容变化时并不会定位到新的sevlet或jsp的网址路径,浏览器感知不到变化。并且,该方式可以将请求reguest和reguest的一些参数、域对象一起传递。
2、respose.sendRedirect(“跳转页面URL”);可以跳转到别的网站,其实是一个get/post请求被sevlet接受后,程序先发回一个302status,浏览器读到302状态后再次发送了一个get请求,请求到别的页面。转发别的网站时,要带https://。
5、.getSession().getServletContext(),可以获取全局的上下文对象。

getPageInfo():与getServletPath()获取的路径互补,能够得到的是“url-pattern”中*d的路径部分
getRequestURL:获取请求的地址链接,全路径(浏览器中输入的地址,不包含参数部分)http://localhost:8080/jqueryLearn/resources/request.jsp
getRequestURI() 返回除去host(域名或者ip)部分的路径 /jqueryLearn/resources/request.jsp
getServletPath():获取当前这个servlet的路径,不包含根路径和虚拟目录。/resources/request.jsp
getContextPath():获取项目的根路径,包含虚拟目录。 /jqueryLearn
getScheme():获取的是使用的协议(http 或https)
getProtocol():获取的是协议的名称(HTTP/1.11)
getServerName():获取的是域名(xxx.com)
getLocalName:获取到的是IP

【ServletContext对象和文件地址问题】
request.getServletContext()方法或httpservlet.getServletContext()方法都可以获取。
ServletContext是一个application对象,一个web工程只有一个ServletContext,我们可以使用它的一些方法进行全局对象的使用和设置。
1、域对象:
Object getAttribute(String name) 获取一个全局属性
void setAttribute(String name, Objt) 设置一个全局属性
removeAttribute(String name) 删除一个全局属性
域对象批量操作:
Enumeration getAttributeNames() 返回一个所有全局属性变量名的集合。
String getInitParameter(String name) 返回一个全局参数<context-param>
Enumeration getInitParameterNames() 返回所有全局参数的变量名
注意:可以通过在web.xml中在根标签下写context-parm来指定项目需要的一些初始化参数:
<context-param>
<param-name> contextconfiglocation</param-name>
<param-value> /</param-value>
</context-param>
2、getMimeType(String file) 返回文件的mime类型。
3、获取文件路径
String getRealPath(String path) 返回某一个url,如根目录"/"在硬盘上的实际地址,该方法通常用于根据url路径加载或操作文件。注意,src目录在打包后会换成classes目录,目录为/web-inf/classes/?
URL getResource(String path) 和realpath一样,但返回值是url类型。
InputStream getResourceAsStream(String path) 将获取到realpath直接转化为文件流。

【respond对象】
1、 resp.getWriter().write;使用打印流来向客户端打印数据,这会重新清空dom文档的内容。在打印之前,应该设置一下头信息,告知浏览器此respond使用的字符集编码。resp.setContentType(“text/html;charset=utf-8”);
同理可知,输出字节数据,使用resp.getOutputstream即可。
2、文件下载。
response.setHeader(“Content-Type”,“text/plain”); video/x-msvideo
response.addHeader(“Content-Disposition”,“inline;filename=” + filename);该方式在页面内显示文件。
type设置返回类型,是原始文件。disposition设置文件的倾向,可以设置打开方式和文件名,inline/attachment前者直接显示在页面上,后者弹出对话框让用户以附件方式下载。
所以,如果想要让用户下载,应该设置:
response.setHeader(“Content-Type”,“text/plain”); video/x-msvideo
response.addHeader(“Content-Disposition”,“attachment;filename=” + filename);该方式以附件方式提醒打开。

【中文乱码问题】
1、 get接收参数乱码
req.getParameterMap()时,默认以iso8859-1编码集将浏览器传递过来的字符进行解码,然后存储为字符串。而一般浏览器是使用GBK或UTF-8编码的,这就会产生解码错误。
byte buf[] = request.getParameter(“name”).getBytes(“iso8859-1”);
String name = new String(buf,“GBK”);
使用该方法可以还原之后再编码。
或者修改tomcat的默认字符集<Connector connectionTimeout=“20000” port=“8080” protocol=“HTTP/1.1” redirectPort=“8443” URIEncoding=“UTF-8”/>
注意,eclipse web工程下的severs也有sever.xml,它会默认覆盖tomcat的设置,所以应该在这里修改。
2、post接收参数乱码
get接收的参数是放在请求体中的,因此可以使用req.setCharacterEncoding(“UTF-8”);将请求体中的字符重编码。
注意:该方法只能重编码请求体中的参数(Overrides the name of the character encoding used in the body of this request),所以使用get方法时设置该参数是无效的。

3、respond发送给客户端乱码
resp.setContentType(“text/html;charset=UTF-8”);
该方法设置sevlet的中文编码,并提醒客户端以该编码解码,无论是使用字符流还是字节流,都可以起作用。

【cookie】
Cookie(java.lang.String name, java.lang.String value)
cookie是服务器在客户端存储的一个纯文本的键值对,可以存放一些服务器标识客户端的信息,可以想象为服务器给客户端做标记。

如何添加?
response.addCookie(cookie);响应返回时可以给客户端进行cookie添加,此时抓包可以看到响应头中多了一个Set-Cookie:name=value字段。cookie的大小和数量是有限制的,客户端也可以设置不接受任何cookie。浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

如何获取?
Cookie[] cookies = request.getCookies();客户端在进行请求时会把浏览器写给自己的cookie标记全都带上,我们可以用该方法获取。当服务器从未给客户端添加标记时,返回null。然后使用cookies的getname、getvalue方法可以获取键值。

cookie的种类和生存周期?
cookie有两种,一种是瞬时的,存储在客户端内存中,当一个客户端存在时,cookie即存在,客户端关闭后,cookie随之清空。
另一种是持久化存在的,以文本形式保存在客户端硬盘上,通过方法cookie.setMaxAge(int time)可以设置其存在的时间,时间以秒计算,时间过了之后cookie就会过期。
疑问:什么是一个客户端?
对于瞬时cookie,一个浏览器窗口是一个客户端,同一个浏览器的不同窗口分属不同的客户端,一个窗口的不同标签是同一个客户端。当然,不同浏览器自然分属不同客户端,只有窗口关闭后属于该浏览器窗口的cookie才会被删除。
注意:对于常用浏览器来说,其实标签和普通窗口都属于同一个客户端,只有点击浏览器的新建无痕窗口/隐身窗口/新建会话等选项时,才会新建新的客户端。
对于持久化cookie,一个浏览器的不同窗口或标签页访问服务端时都会带上存储的cookie,此时它们是一个客户端,不同的浏览器才能区分为不同的客户端,但也有例外,使用统一内核的浏览器如360、Chrome存储cookie位置一样,很可能会被识别为同一个客户端。

服务器不同sevlet/jsp对cookie的读取权限?
这涉及到添加cookie时的设置权限问题,这里先讲路径权限(path):
setPath(java.lang.String uri),该方法可以设置应用下什么路径的文件可以访问客户端cookie。
假如有url为localhost:8080/webappname/sevlet.asp/…;
1、 sevlet.asp或其他任意一级应用设置的cookie默认的setpath是(sevlet.asp),则只有该文件及它的子路径文件如sevlet.asp/xx可以访问。它的同级路径文件和父级路径文件不可以访问它设置的cookie。
2、如果要设置一个服务器上的所有项目都可以访问,应设置cookie.setPath("/"),表明根路径下所有路径应用都可以访问设置的cookie。
3、如果有多条设置path的语句,以最后一条生效。
再将一些域名权限(domain);
setDomain(java.lang.String pattern) ,该方法设置什么样的域名模式可以访问应用设置的cookie.
1、默认情况下,该选项设置为本机服务器的域名。
2、pattern只能以.开头,一旦设置的域名,必须以域名才能访问,以localhost和ip访问将不能获取cookie。
3、设置了其他域名后,除了设置的域名,本机域名也还是能够获取cookie的。
4、cookie作用域为父级域名时,所有子级域名都可以得到该cookie,但域名不能设置为顶级域名,否则cookie无效。实际上,cookie只能跨三级域名共享,即使设置了一个二级域名,二级域名下的应用也是不能和本机共享cookie的。
5、如果没有映射域名,尽量不要使用setdomain。

如何删除一个持久化的cookie?
这要说道cookie的一个特点,同名的cookie会覆盖前一个,所以我们只要new一个同名cookie,设置cookie.setMaxAge(0)(表示立即删除的cookie),覆盖到客户端即可。这要,可以使用同样的首发将持久化cookie转化为瞬时cookie,cookie.setMaxAge(-1)(负数表示瞬时的cookie)。

【session】
session是服务器内存开辟的一块区域,它标识一个客户端会话,可以存储标识宿主为某固定客户端会话的一些信息。
如何得到session?
session是和客户端相关的,自然只能由客户端访问时通过请求对象来获得:HttpSession reguest.getSession(boolean create) (create为true时,若该请求没有session,会自动创建一个;如果为false,则没有会话时返回null)。

session有什么用?
可以用来让客户端在服务器上存储数据:void setAttribute(String name, .Object value)
显而易见,比起cookie只能存储文本,它可以在服务器上存储任何数据结构。

session如何标识一个会话?
session是基于瞬时cookie的,瞬时cookie怎么标识一个客户端,它就怎么标识一个会话。也即一个浏览器的一个窗口(包含不同标签)识别为一个会话。实际上,我们在执行getsession时,系统会默认写回客户端一个JSESSIONID的cookie,作为该客户端的session标识。

session的生存周期?
服务器使用reguest.getSession时,session即生成,会话关闭后,session不会立即删除,它还会在有效期内保留,直到过期或服务器关闭为止。有效期是从浏览器关闭后开始计算的。我们可以用以下方法设置session的有效期:
setMaxInactiveInterval(int interval) interval以秒即时,默认为30分钟,设置为负值将永久保留。
getMaxInactiveInterval()
当然,也可以手动销毁session:即调用invalidate()的方法。
需要注意的是,虽然session还能在有效期内保留,但当客户端再次请求时,并不会继承这个session,因为客户端的id已经清除,系统会分配新的session给这个客户端,除非程序手工指定它继承这个sessionid。
判断有没有过期的方法:
if(nullrequest.getSession(false)){???
???
if(true
request.getSession(true).isNew()){
//新的会话,这一步会创建新的session
}

else{

System.out.println(“session已经过期”);???

}
}

服务器不同sevlet/jsp对cookie的读取权限?
session是项目级变量,一个项目工程下不同文件共享同一个sevelet,如果想要跨项目使用,可以考虑存储到application级别的sevletcontext中。

session常用方法:
setAttribute(string name, Object value)
Object getAttribute(String name)
removeAttribute(String name) 删除变量
Enumeration getAttributeNames() 获取绑定在session上的所有参数名。

getId() 获得session的id,这实际上是客户端的一个cookie变量。
long getCreationTime() 获取long类型的创建时间
long getLastAccessedTime() 返回上次访问时间

boolean isNew() 该session是否是新创建的
invalidate() 设置该session立即失效。

【过滤器filter】
@webfilter("/*")
实现 Filter接口即可。
init(filterconfig fc);
doFilter(servletrequest req,servletresponse resp,filterchain filter){
//放行之前
filter.dofilter(req,resp)
//回来之后
}
destroy();
也可以用xml方法进行配置:
<filter>
<filter-name> HelloWeb</filter-name>
<filter-class> helloweb.HelloWeb</filter-class>

</filter>
<filter-mapping>
<filter-name> HelloWeb</filter-name>
<url-pattern> /*</url-pattern>
</filter-mapping>
生命周期:单例模式,服务器启动和正常关闭时自动实例化和销毁。
拦截方式配置:
可以根据访问方式来分类拦截请求:
注解方式:
设置dispatcherTypes属性,可以使用{}配置多个值:
1、request:默认值,只拦截浏览器直接访问的请求。
2、forword:只拦截转发请求
3、include:只拦截jsp包含的请求。
4、error:只拦截错误跳转的请求。
5、async:拦截ajax异步访问的请求。
xml方式:
<filter-mapping> 标签下可以设置<dispatcher> 标签。
过滤器链先后顺序:
注解方式:类名字符串ABC比较规则,小的先执行。
xml方式:按照文件定义的顺序执行。

【监听器 listenner】
实现sevletcontextlistenner接口并完成配置即可:
服务器启动后自动创建。
void contextdestroyed(servletcontextevent sce)
void contextinitialized(servletcontextevent sce)
配置:
xml方式:
<listenner>
<listenner-class> htyy.mylistenner</listenner-class>
</listenner>
注解方式:
@weblistener即可

【【jsp】】

jsp是一种类HTML标签语言的文件格式,但区别于静态的HTML,JSP可以动态地生成标签内容。它实际上是基于java翻译引擎的,文件内所有HTML语言会在编译时被java的jspout对象原封不动打印(println)出来,而java代码则可以灵活调用out或respond.getwriter对象来进行打印,这样,就可以动态(根据不同客户端访问或根据不同的控制情景)地生成不同的html页面了。
out和getwriter的区别?
jspout对象是基于getwriter的,它打印的内容是默认放置到writer的缓冲区队列中,所以如果jsp页面中有out.print语句,他在页面上是顺序输出的。但如果有writer.pinrt语句,页面默认先输出respond本身要输出的内容。
jsp什么时候编译执行?
web启动时jsp文件并不会自编译,而是第一个客户访问时,才会编译执行成class文件,从第二个客户端开始,访问的就是编译完成后的class文件了。

JSP语法】
0、<%@ %> 系统指令,比如设置文件类型、是否跳转错误页面、引入页面和导包等。
1、 <%! %> 该标签用于声明全局变量及类的方法。
2、<%= %> 输出变量到html。用在诸如<a href= <%= user.name%> ;> 时,可以取变量值。单独写在文件中时,等价于out.print,输出。使用第一种情况时,应该注意造成null的情况。
3、<% %> 该标签用于执行java代码,相当于写在service方法中的java内容。
其他语法见以下的三大编译指令+三个动作标签内容。

【三大编译指令】
写法:<%@ 指令名字 %>
编译指令的意思是该指令在编译期间执行的指令,文件只编译一次,因此指令只执行一次,编译期间第一个用户刚刚访问,因此这些指令都是不可使用reguest参数的。

page指令】

<%@page 属性名=属性值… %> 常用属性介绍:
language=“script language” 指明使用的编程语言,jsp中当然只能指明java,不常用
buffer=“none | kb size” 设置缓冲区,默认8KB,不常用
outoflush=“true | false” 是否自动缓冲,默认ture,不常用
isthreadsafe=“true | false” 是否线程安全,默认ture,不常用
extends=“xx” 默认继承了jspservice,不用修改,不常用。
session=“true | false” 默认为ture,在该页面启用session内置对象。保持设置即可。

contentype=“text/html;charset=“utf-8” 和sevlet中的一样,常用。
import=”" 显然,用来导包,快捷键自动使用。
errorPage=“url name” 发生错误转到那个页面,常用
isErrorPage=“true/flase” 该页面是否是一个用来显示错误信息的页面。

###include】
<%@ include file=“other02.jsp”%>
编译时,把另一个页面的所有内容全部拿过来,放置到指令所处的地方,相当于C的#define预编译指令。实际上就是查找替换,因此这里的file是不可带参数的。和下面要将的动作指令中的include需要做区别。

taglib】

<%@ taglib prefix="" uri=""%>
导入另外的标签库,prefix是标签库的别名/前缀,url是其路径地址。
如:<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
那么标签就可以使用<c: > 来进行快捷键提示。

【三个动作标签】
写法:<jsp:xx > </jsp:xx>

  • jsp:include
    <jsp:include page=“other02.jsp”> </jsp:include>
    区别于编译指令的include,但这里是动态包含,也就是不把包含的页面所有元素标签全部拿过来输出,而是把它的运行结果拿过来。 而且它是编译后的指令,也就是说,程序如果没有运行到这个指令,页面上绝对是没有任何与other02相关的内容的。
    同时,因为它是动态包含,自然是可以给包含页面传递参数的,但不能使用?name=value传递,需要使用param标签,详见第三个动作标签param。

  • jsp:forward
    <jsp:forward page=""> </jsp:forward>
    相当于request.getRequestDispatcher("").forward(request, response);
    如果跳转到自己,有刷新页面的效果。
    当然,它也是可以通过param标签传递参数的。

  • jsp:param
    <jsp:forward page=“other02.jsp”>
    <jsp:param value=“beijing” name=“address”/>
    </jsp:forward>

可以在include/forword标签中嵌套该变迁,用以传递参数。
需要注意的是,它相当于reguest.setparam(“beijing”,“address”),然后将reguest传递。所以即使没有传递任何参数,在另一个页面使用reguest.getparam也是可以得到原先客户端请求携带的参数的。当然,如果1页面对参数修改了名称,那就得不到了,如果1页面也设置了同名参数,那么会产生覆盖。

【jsp 9大内置对象】
> 所谓内置对象,就是我们可以直接在jsp页面中使用这些对象。 不用创建。
四大作用域对象:

  • pageContext
  • request
  • session
  • application
    这些对象可以存值,不限于文本类型。
    <%=pageContext.setAttribute(“name”, “page”);%>
    <%=pageContext.getAttribute(“name”)%>
    pegecontext是局部变量,离开页面失效,页面刷新回复初始值;
    request 存储在请求中的变量,一次请求(请求转发)有效,响应即结束。该对象等同于sevlet的reguest。另外,reguest的参数其实可以通过getattribue(“param”)取得,返回值是一个数组。
    session 等同于sevlet的session,一次会话有效。
    application 等同于servetcontext对象,整个web工程有效,永不过期。

其他五个对象:

  • out 【JspWriter】对象,用于输出。
  • response 等同于sevlet的HttpServletResponse对象。
  • exception 异常,可以自动传递给设置的errorpage页面。
  • config ServletConfig配置对象。
  • page 就是这个jsp翻译成的java类的实例对象,可以由该对象得到其他8个对象。

【EL表达式】
写法:KaTeX parse error: Expected 'EOF', got '&' at position 30: …域中取值,纯用于取值时,等价于&̲lt;%= %&gt; 写法,…{5==5}或KaTeX parse error: Expected 'EOF', got '&' at position 25: …返回ture 2、逻辑运算符 &̲&/and ||/or !/n…{true and flase} 返回false
3、算术运算
±*/ 如: 365 + 24 4 、 其 他 运 算 e m p t y 运 算 符 如 {365+24} 4、其他运算 empty运算符 如 365+244empty{empty user}
注意,并不完全等价于${user eq null},因为它判断null和空字符串""都返回true。
二元表达式 ?:
[]和.号运算符。

取值方法:
"${作用域.标识符}"当省略标识符时,分别从pageScope、requestScope、sessionScope、applicationScope四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。
所谓标识符,就是setattrbute是设置的名称,如:
<% request.setAttribute(“person”,person);%>
${person}即可取得一个person对象。
<% request.setAttribute(“list”,list);%>
${list} 即可取得一个list集合对象。
<% request.setAttribute(“map”,map);%>
${map} 即可取得一个map对象。

另外,配合[]和.运算符可以从这些对象中取值。
1、从对象取值
${person.age} 取得对象的某属性
${person.address.name} 取对象属性(该属性是一个对象)的属性
2、从list、数组中取得元素
${list[1]} 取得数组、list的第二个元素,因为下标从0开始。
${list[1].name} 取得数组或list的第二个元素对象的某属性。
3、从map中取值。
${map.name } 取得map中key为name的value。
${map.name.firstname }略

注意:如果两个作用域中含有同名对象,应该指定作用域。另外,如果属性或map的key中含有关键字".",不应该再用.取值,应该用[]。
注意:{}中如果不是常量和关键字运算符,就会识别为变量,那就就会去作用域中找了。
注意:el表达式只能取到显式放置到四个作用域中的变量,直接在<%! %> 声明的变量不能用el取到。

【11个EL内置对象】
${ 对象名.成员 }

  • pageContext
    作用域相关对象
  • pageScope
  • requestScope
  • sessionScope
  • applicationScope

头信息相关对象

  • header
  • headerValues

参数信息相关对象

  • param
  • paramValues
  • cookie
    全局初始化参数
  • initParam

【JSTL】
全称 : JSP Standard Tag Library jsp标准标签库>
用于简化jsp的代码编写。 替换 <%%> 写法。 一般与EL表达式配合

引入jsp文件:

  1. 导入jar文件到工程的WebContent/Web-Inf/lib jstl.jar;standard.jar,注意需要导入两个文件,但不用构建buildpath。
    <dependency>
    <groupId> javax.servlet</groupId>
    <artifactId> jstl</artifactId>
    <version> 1.2</version>
    </dependency>
    <dependency>
    <groupId> taglibs</groupId>
    <artifactId> standard</artifactId>
    <version> 1.1.2</version>
    </dependency>

  2. 在jsp页面上,使用taglib 指令,来引入标签库,注意,请导入1.1版本,它支持el表达式。
    <%@taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %> 另外,如果要使用它的fn函数包,也可以使用fn库:
    <%@taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/functions” %>

  3. 如果新建jsp文件的默认编码格式不是中文格式,应该修改eclipse的默认web编码:【window】-【Perferences】-【JSP File】-【Encoding】
    4.如果el表达式不运算,可以加标签<%@ page isELIgnored=“false” %>

不常用标签:
out标签
<c:out value=”要显示的数据对象” [escapeXml=”true|false”] [default=”默认值”]/> 或
<c:out value=”要显示的数据对象” [escapeXml=”true|false”]> 默认值</c:out>
out标签可以给输出指定默认值。对于默认值的识别,有如下情况:
el表达式 找 不 到 返 回 " " 的 情 况 可 以 替 换 为 默 认 值 。 {} 找不到返回""的情况可以替换为默认值。 ""{null}可以替换为默认值。
<%=x%> 的情况,x如果是空字符串,直接输出空字符串。如果是null,可以替换为默认值。
value="" 双引号里直接什么都没有,打印空字符串;如果有null,将null打印为字符串。
escapexml 设定为ture时,所有<> &"和&lt&gt都表现纯文本模式。。设定为false,<> 会被识别为标签,&lt&gt会被识别为<> 的纯文本。默认是ture
也就是说,<> 的true和&lt&gt的false 输出的都是 <> 网页纯文本。

set标签】
<c:set var=“name” value=“zhangsan” scope=“session”> </c:set>
相当于:<%session.setAttribute(“name”,“zhangsan”);%>
var 是变量名 value是变量值 scope 是存储到哪个作用域,默认是page局部变量。scope=”page|request|session|application”
注意,没有get标签,因为完全可以用el表达式代替。

<% Person person=new Person(); %>
<c:set target="${person}" property=“name”> 孤傲苍狼</c:set>
target 必须是一个javabean property是其属性名,标签内是属性值。
相当于<% person.name=“孤傲苍狼”%>

常用标签:
if标签】test内容一般结合el表达式一起写。
<c:if test="${ age > 26 }" [var=""]>
<h1> 年龄大于了26岁…<h1>
</c:if>
test接受布尔值,可以使用<%= %> 或el表达式 标签内就是会执行的内容。
var=可以用一个变量名来存储true、false
if标签没有else,如果要判断另外的分支只能再写一个if标签。

foreach标签】
<c:forEach begin=“1” end=“10” var=“i” step=“2”>
KaTeX parse error: Expected 'EOF', got '&' at position 6: {i } &̲lt;/c:forEach&g…{pagescope.i}

<c:forEach var=“user” items="${list }">
u s e r . n a m e − − − − {user.name } ---- user.name{user.age }
</c:forEach>
items:要遍历的变量名称
var:items的每一个子元素

<c:forEach var=“fuwa” items="${list}" begin=“1” end=“3” step=“2”>
{fuwa}
</c:forEach>
结果是取得了list的第二个和第五个(list下标从0开始,每隔两个取一个)

foreach标签还有一个有用的属性,varStatus,如果用一个变量存储它:varStatus=“s” ,它有四个属性
${s.index} 所在位置,即索引
${s.count} 总共已迭代的次数
${s.first} 是否为第一个位置
${s.last} 是否为最后一个位置

choose标签:】
相当于switch case
 <c:choose>
<c:when test=“条件1”>
      //业务逻辑1
<c:when>
    <c:when test=“条件2”>
      //业务逻辑2
<c:when>
    <c:when test=“条件n”>
      //业务逻辑n
<c:when>
<c:otherwise>
      //业务逻辑
    </c:otherwise>
 </c:choose>

注意!】el和jstl是互通的,所以el可以取得jstl定义的变量,但它们和<% %> 定义的变量是不互通的,除非显示放置到相关作用域,否则不能取到<% %> 和<%!%> 定义声明的变量。

【javabean】使用标签new java对象
<jsp:useBean id=“person” class=“gacl.javabean.study.Person” scope=“page”/>
┝<jsp:useBean> :表示在JSP中要使用JavaBean。
┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
┝class:此对象对应的包.类名称
┝scope:此javaBean的保存范围,四种范围:page、request、session、application

<jsp:setProperty name=“beanName” property=“propertyName” value=“string字符串”/>
┝name属性用于指定JavaBean对象的名称。
┝property属性用于指定JavaBean实例对象的属性名。
┝value属性用于指定JavaBean对象的某个属性的值,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。

<jsp:getProperty name=“beanInstanceName” property=“PropertyName” />
   ┝name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean> 标签的id属性值相同。
   ┝property属性用于指定JavaBean实例对象的属性名。
如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty> 标签输出该属性的结果将是一个内容为“null”的字符串。

【sevlet、html、jsp中的路径问题】
1、相对本身文件位置的相对路径
sevlet看映射的虚拟路径,其他jsp、html、js、css文件看存放在项目中的位置,如果最终在浏览器访问的url同级,就可以直接使用文件名访问。如果不同级,那么使用…/ /等相对路径访问。
2、相对根路径的相对路径。
在服务器端,也就是servlet和jsp中的java代码部分,/根路径是项目文件夹的位置。
在客户端,也就是HTML、css和jsp中的html代码部分,/根路径是服务器网址,也即是localhost:8080的地址。需要注意的是,js文件中的路径不以自身为准,以引用它的html文件为准,所以无论js文件在哪,效果都相当于写在文件里。
3、实际开发中使用相对根路径的方式。此方式也有两个区别:
1)客户端使用,即页面请求时、重定向时,需要使用全目录,即虚拟目录也要加上。
2)服务器使用,即转发时,不需要虚拟目录,直接相对根路径即可。

【【个人小贴士】】
1、如果在一个sevlet刷新页面,那么它request中的请求参数信息会重新获得,包括地址栏参数和post表单参数。如果是post参数,浏览器可能会弹框提示将重新获得表单数据。所以设计程序时,尽量让页面不留在用于增加、删除、修改的sevlet,如果不能留在jsp页面,尽量留在专门显示的sevlet页面。
2、通过reguest.setattribute传递参数,必定要使用请求转发,所以无论中间经过多少个处理界面,url始终在sevlet界面。
3、浏览器刷新会重新发送http请求。但常规网页的前进后退不是,访问的是在浏览器的缓存中保留了访问的内容。当然,很多程序可以强制回退时从服务器刷新页面。
4、防表单重复提交技术:日常开发中,因为网速等原因,用户可能会停在提交页面点击多次提交按钮,这就会产生多次提交。而由于开发原因,给了用户停在处理提交的doformsevlet的机会,在该页面刷新也会导致多提交。维持,就有了防多提交技术。
4.1 JavaScript实现:
<script type=“text/javascript”>
var isCommitted = false;//表单是否已经提交标识,默认为false
function dosubmit(){
if(isCommitted==false){
isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
return true;//返回true让表单正常提交
}else{
return false;//返回false那么表单将不提交
}
}
</script>
4.2 JavaScript实现方式2:
function dosubmit(){
//获取表单提交按钮
var btnSubmit = document.getElementById(“submit”);
//将表单提交按钮设置为不可用,这样就可以避免用户再次点击提交按钮
btnSubmit.disabled= “disabled”;
//返回true让表单可以正常提交
return true;
}
这两种可以防止网速原因,但开发原因无法防止。
4.3 利用session防重提交。原理为:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。在Form表单中使用隐藏域来存储这个Token,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了。关键代码: <input type=“hidden” name=“token” value="${token}"/> token可以用uuid设置在session中。
具体实现见:https://www.cnblogs.com/xdp-gacl/p/3859416.html
5、如何在cookie中存储中文。可以先用工具类转为特定字符串存储java.net.URLEncoder.encode(“天下无敌”, “utf-8”),解析时再解码java.net.URLDecoder.decode(encode, “utf-8”)。

【【idea使用学习】】

配置教程】:
初始配置:https://blog.csdn.net/isea533/article/details/53706744/
web工程配置:https://www.cnblogs.com/yangyquin/p/5285272.html
1、创建空的java工程,作为workspace使用。
2、创建一个Module,作为具体工程。勾选“Web Application” -> 确认已勾选“Create web.xml” -> Finish。
3、在web/WEB-INF下创建两个文件夹:classes和lib。
4、配置文件夹路径。
File -> Project Structure (快捷键:Ctrl + Shift + Alt + S) -> 选择Module :
选择 Paths -> 选择"Use module compile output path" -> 将Output path和Test output path都选择刚刚创建的classes文件夹。
接着选择Dependencies -> 将Module SDK选择为1.7 -> 点击右边的“+”号 -> 选择1 “Jars or Directories”
-> 选择刚刚创建的lib文件夹> 选择“jar directory” ->
5、配置Tomcat容器
在"Run/Debug Configurations"窗口的"Server"选项板中,取消勾选"After launch",设置"HTTP port"和"JMX port"(默认值即可),点击 Apply -> OK, 至此Tomcat配置完成。
6、idea中sevlet不会自己创建urlmaping,但可以在类名上添加:<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

使用注解配置selvelt虚拟路径】:
这是Servlet3.0新特性(得Tomcat7.0版本及以上),@WebServlet 用于将一个类声明为 Servlet,,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。该注解具有下表给出的一些常用属性(以下所有属性均为可选属性,但是 value 或者 urlPatterns 通常是必需的,且二者不能共存,如果同时指定,通常是忽略 value 的取值)
name 类名,等价于sevlet-name。如果没有显示置顶,取值为类的全限定名。
value
urlPatterns 字符串数组,和value只能存在一个指定一组url匹配模式。等价于<url-pattern>
loadonstatup 等价于<load-on-startup>
如@WebServlet(name=“LoginAction”,urlPatterns={"/LoginAction","/LoginAction2"})
或者@WebServlet(name=“LoginAction”,value={"/LoginAction","/LoginAction2"})
@WebServlet("/LoginAction")
创建create sevlet是,可以在输入框写url,回车隔开。

结构】:
project是一个完整的项目,module是项目中的一个小模块。同时一个module还可以包含多个module。
一个Project可以有多个Module。目前,主流的大型项目结构基本都是多Module的结构,这类项目一般是按功能划分的,比如:user-core-module、user-facade-module和user-hessian-module等等,模块之间彼此可以相互依赖。通过这些Module的命名可以看出,它们都是处于同一个项目中的模块,彼此之间是有着不可分割的业务关系的。
dea中的project和Module是一种父子的关系,Module之间是一种兄弟关系,或者是一种依赖关系。
例如在idea中用maven搭建了一个project,在project中有两个Module,那么这个Module中的共同的依赖包就可以放在project中的pom.xml文件中,在eclipse中的workspace和project是不可以的。

【和eclipse创建web项目的不同】
常规使用eclipse时,项目是默认发布到tomcat文件夹下的,但idea不同,它并不发布到tomcat文件夹下,而是每个项目各自到 {user.home}/.IntelliJIdea/system/tomcat文件夹下创建自己的配置文件夹,每个配置文件夹以tomcat版本号+项目名命名,如Tomcat_7_0_91_myprj,文件夹下有conf/logs/work三个文件,conf中的Catalina\localhost文件夹存放着自己的xml配置文件。log中记录自己项目运行时的日志,work记录自己的jsp源码文件。当idea启动tomcat时,会让它读取指定位置的配置文件,找到项目位置,然后就可以运行起来了。使用这种方法运行,tomcat只运行配置文件记录的项目,并不会运行自己webapp目录下的项目。当然,正常启动tomcat,它因为不会自己去早C盘的配置文件,自然不会运行idea的项目了。

【智能提示】
alt+enter自动修复代码,包括创建测试类,提供错误解决办法,提示for循环等。出现灯泡时可以看下系统提供的建议。
alt+/ 类名提示,根据部分字母提示完整类名或方法名,也能提示参数列表。
shift+ctrl+space 智能提示,提示方法的参数及返回值用法等。
ctrl+p 在方法括号中提示参数类型的列表。

【智能补全】
用于生成Construct、Getter/Setter、toString等 Alt + Insert
自动完成代码,添加右括号,分号之类 ctrl+shift+enter
生成包围代码 Ctrl + Alt +T
取消代码包围 Ctrl + Shift + Delete
重写覆盖方法 Ctrl + O
实现接口方法 Ctrl + I

【代码重构】
提取当前选择为局部变量 Ctrl + Alt + v
提取当前选择为成员变量 Ctrl + Alt + f
提取当前选择为常量 CTRL+ALT+C
提取当前选择为方法 CTRL+ALT+M
当前方法内局部变量抽取为参数 CTRL+ALT+P
显示重构列表 Ctrl + Alt + +shift + v

【常用功能】
重命名:格式化代码Ctrl+Alt+L。
代码重构:Ctrl+Alt+F。
清除不必要的import Ctrl+Alt+O
格式化import列表Ctrl+Alt+O
格式化代码 Ctrl+Alt+L/f。

【移动与编辑】:
Ctrl+W Ctrl+Shift+W 向左向右跳单词选中代码
Ctrl+Left/Right 移动光标到前/后单词
Ctrl+shift+Left/Right/ 向左向右选中单词
Alt+Forward/Backward 移动到前/后方法
Ctrl+Y删除行、Ctrl+D复制行、Ctrl+</> 折叠代码

【其他】:
Ctrl+Alt+T创建单元测试用例
Alt+Shift+F10运行程序,Shift+F9启动调试,Ctrl+F2停止。
F7/F8/F9分别对应Step into,Step over,Continue。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值