JavaWeb基础
第一节 TomCat
Tomcat是一个 servlet JSP(java server page) 规范的容器。
其他服务器如weblogic,实现J2EE规范。
bin目录:
startup.bat windows环境下的批处理程序
startup.sh linux环境
conf目录:
server.xml :Tomcat将来是根据我们配置的这个xml运行的。
服务器一直在监听8080端口,被动地等待请求提供响应服务。
https 默认是443端口
TOMCAT配置:
-
系统变量 ,新增 变量名:CATALINA_HOME,变量值:tomcat根目录在你电脑中的路径
-
PATH中 ,末尾新添加 ;%CATALINA_HOME%\bin;%CATALINA_HOME%\lib
-
运行命令行 ,在tomcat目录\bin目录中, service.bat install,稍候提示 the service “tomcat8” has been installed ,则表示成功
-
在tomcat\bin目录 ,双击 tomcat8W.exe 图形界面程序 ,在弹出的图形界面中 ,点击start ,运行tomcat ,浏览器输入localhost:8080 ,访问成功则完成配置
常见问题
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
https://blog.csdn.net/znn626/article/details/7893555
通过startup.bat脚本启动tomcat时,cmd命令窗口闪现问题
startup.bat启动tomcat时的流程是:startup.bat—>Catalina.bat—>setclasspath.bat
,闪退说明JAVA_HOME和JRE_HOME这两个环境变量都没有配置
解决方法:
(1).在已经解压的tomcat中bin文件夹里找到startup.bat文件,在文件头的位置加入下面一行代码就能解决问题 SET JAVA_HOME=(java jdk目录)
同样的也需要在tomcat中的shutdown.bat脚本中(关闭tomcat)加入相同的一句话即可
第二节 HTTP协议简介
GET:向服务器请求数据 参数带在请求路径后面,参数是暴露的,不适合提交敏感数据,所以一般不用来提交数据,只是用来获取数据。长度是有限的。
POST:向服务器提交数据,比如注册,post请求无大小限制,可以处理敏感数据。典型的就是提交表单操作。
HTTP状态码:
200 请求OK
400 请求错误,可能是语法问题
403 没有权限
404 请求路径找不到
500 服务器错误
第三节 servlet简介
servlet 是sun公司定义的一组javaAPI ,专门用于处理网络请求。
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern></url-pattern> //地址
</servlet-mapping>
地址栏输入不同的URL,找到对应的servlet-name,再找到对应的类,然后处理get和post,把数据返回给浏览器。
怎么在IDEA中配置servlet
1.创建一个类并实现Servlet接口
2.在web.xml文件中对Servlet进行配置
<servlet>
<servlet-name>ServletDemo1</servlet-name> //别名
<servlet-class>ServletDemo1</servlet-class> //类名
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name> //别名
<url-pattern>/demo1</url-pattern> //访问请求后缀
</servlet-mapping>
第四节 servlet运行流程
Servlet的生命周期
public HttpServlet() {
}
服务器启动的时候,HTTPservlet就会首先被初始化,此时ServletDemo1(servlet-class)还没有被初始化。
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
...
}
当提交访问请求时(地址栏回车),servlet又会执行构造函数,此时初始化的是ServletDemo1(servlet-class),接下来执行service方法,调用实现子类(ServletDemo1)的doGet()。
即访问会初始化URL所对应的Servlet,执行service方法,执行GET或POST方法
第二次访问的时候不会初始化对应servlet,直接一直调用service方法,执行GET/POST
第五节 GET POST 参数提交 以及中文乱码
web/demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="http://localhost:8080/web_day1_war_exploded/demo1?name=test&pwd=******">模拟一个get请求</a>
<form action="http://localhost:8080/web_day1_war_exploded/demo1" method="post">
<input type="text" name="nameP">
<input type="text" name="pwdP">
<input type="submit" value="提交表单">
</form>
</body>
</html>
src/ServletDemo1
public class ServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name=request.getParameter("nameP");
String pwd=request.getParameter("pwdP");
System.out.println(name+" "+pwd);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get请求是没有办法改变编码的
String name=request.getParameter("name");
String pwd=request.getParameter("pwd");
System.out.println(name+" "+pwd);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
</web-app>
表单提交中文时乱码(è??? pwd)
POST:
大部分浏览器使用的是Unicode编码,Tomcat默认 ISO-8859-1 编码
String name=new String(request.getParameter("nameP").getBytes("ISO-8859-1"),"UTF-8");
将参数用Tomcat的iso-8859-1编码成二进制数组,再用你所使用浏览器的编码方式解码成字符串传递回去即可。
GET:
开发时应尽量避免在get请求中带有中文参数
当URL拼接后,浏览器对其进行encode,然后发送到服务器。tomcat服务器会根据设置的URIEncoding来进行解码,如果没有设置则会使用默认的ISO-8859-1来解码,那么服务器进行解码时就会产生乱码。
可以修改server.xml中的 Connector,增加 URLEncoding=“UTF-8”,useBodyEncodingforURL=“true”
第六节 req其他方法 resp方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name=new String(request.getParameter("nameP").getBytes("ISO-8859-1"),"UTF-8");
String pwd=request.getParameter("pwdP");
String a=request.getContextPath(); //获得工程名
String b=request.getRequestURI(); //定位到你访问的servlet的地址
String c=request.getRequestURL().toString(); //访问资源的全路径
String d=request.getRemoteAddr(); //获取客户端IP地址
String e=request.getRemoteHost(); //获得客户端的主机名
Map<String,String[]> map=request.getParameterMap();
//记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。返回值只能读,不像普通的Map类型数据一样可以修改。
System.out.println(name+" "+pwd);
}
第七节 过滤器 Filter
Filter的职责:
-
在请求访问后端资源时拦截它
-
管理从服务器返回给客户端的响应
Filter在Tomcat启动时就已经初始化了。
Filter责任链执行的顺序是根据在web.xml中配置的顺序决定的。
web.xml
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
EncondingFilter(乱码过滤器)
public class EncodingFilter implements Filter {
private String encode="UTF-8";
public void destroy() {
System.out.println("过滤器销毁了");
}
//统一设置编码
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//把doPost和doGet获取的请求、响应转型
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)resp;
//统一设置编码
req.setCharacterEncoding(encode);
resp.setContentType("text/html;charset="+encode);
chain.doFilter(req, resp); //责任链模式
//chain 调用下一个过滤器的方法,把过滤器穿成一串,一个一个地往下走
}
public void init(FilterConfig config) throws ServletException {
encode=config.getInitParameter("encoding");
System.out.println("过滤器初始化");
}
}
第八节 监听器 Servlet三大域
servlet三大域:
request 请求域 生命周期很短 ServletRequest
session域(会话域) 默认30分钟左右 控制登录,标识登录状态以维持会话 HttpSession
context域 (应用域) 伴随着整个应用 ServletContext
<listener>
<listener-class>MyListener</listener-class>
</listener>
public class MyListener implements ServletRequestListener {
// Public constructor is required by servlet spec
public MyListener() {
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request摧毁啦");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("请求来啦,参数是:"+servletRequestEvent.getServletRequest().getParameter("nameP"));
}
}
加了监听器后,之前的demo.html提交表单又出现了乱码,是因为监听器在过滤器之前先获取了参数,servletRequestEvent.getServletRequest().getParameter(“nameP”)应当删除以解决问题。
第九节 Session与Cookies
客户端请求服务端,服务端(Tomcat)会开辟一块内存空间为每一个用户的浏览器创建一个其独享的Session对象,存储结构为ConcurrentHashMap。它用于弥补HTTP无状态特性,服务器可以利用session存储客户端在同一个会话期间的一些操作记录。(看看你在网站上干了点啥)。
cookie的是很小的一段数据(严谨字符串),由服务器发送到用户的网络浏览器。浏览器可以存储它,有效时间内再次访问服务器将会在下一个请求的Request Header中发送回同一服务器。
第一次访问时会生成一个叫JSESSIONID的cookie。
通常,它用于判断两个请求是否来自同一个浏览器 - 例如,保持用户登录。它记住无状态的HTTP协议的有状态信息。
Cookie cookie= new Cookie("name",nameV); //name-value
cookie.setMaxAge(60*60); //为cookie设置有效期
response.addCookie(cookie);
cookie中的name和value中不能使用分号(;)、逗号(,)、等号(=)、空格、美元符(¥)等。
//获取cookie
Cookie[] coo=request.getCookies();
for(int i=0;i<coo.length;i++){
System.out.println(coo[i].getName());
System.out.println(coo[i].getValue());
}
session与cookies的区别和联系:
cookie把用户的数据写给用户的浏览器。
session把用户的数据写到用户独占的session中(即保存在服务器端)。
session的实现基于cookie。
session的实现机制
服务器如何判断客户端发送过来的请求属于同一个会话?
用session id区分;session id 相同服务器就认为是同一个会话
服务器、客户端如何获取sessionID?SessionID在期间是如何传输的?
服务器第一次接收到请求时,开辟了一块Session空间,同时生成一个Session id,并通过响应头的Set-Cookie:“JSESSIONID=XXXXXXX”命令,向客户端发送要求设置cookie的响应; 客户端收到响应后,在本机客户端设置了一个JSESSIONID=XXXXXXX的cookie信息,该cookie的过期时间为浏览器会话结束
服务器只会在客户端第一次请求响应的时候,在响应头上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下来在同一个会话的第二第三次响应头里,是不会添加Set- Cookie:“JSESSIONID=XXXXXXX”信息的(当然你的其他提交操作依然会被记录并设置cookie); 而客户端是会在每次请求头的cookie中带上JSESSIONID信息
用户设置浏览器禁用Cookie后如何使用Session?
禁用Cookie后,我们可以为页面中每条请求增加一个参数,用于发送Session ID的值。
在Java中,通过request对象的getSession方法获取session对象,getSession方法会先判断请求是否发送了含有Session ID的Cookie过来,如果没有,则会判断请求中是否发送了保存Session ID的参数过来。这两种情况下都未能获取到Session ID的话,服务器则判定还未替当前用户创建独占的session,并为用户进行创建。
第十节 JSP JSTL标签 EL表达式
JS的垂死挣扎:EL表达式
JSP EL既可以用来创建算术表达式也可以用来创建逻辑表达式。在JSP EL表达式内可以使用整型数,浮点数,字符串,常量true、false,还有null。
JSP EL允许您指定一个表达式来表示属性值。一个简单的表达式语法如下:
${expr}
其中,expr指的是表达式。在JSP EL中通用的操作符是".“和”[]"。这两个操作符允许您通过内嵌的JSP对象访问各种各样的JavaBean属性。
${name}
${user.name}
${user.age}
jstl
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
根据JSTL标签所提供的功能,可以将其分为5个类别。
- 核心标签
- 格式化标签
- SQL 标签
- XML 标签
- JSTL 函数
IDEA使用JSTL需要在project structure中导入对应的包,web.xml 文件中添加以下配置
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>
<taglib-location>/WEB-INF/fmt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/fmt-rt</taglib-uri>
<taglib-location>/WEB-INF/fmt-rt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core-rt</taglib-uri>
<taglib-location>/WEB-INF/c-rt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/sql</taglib-uri>
<taglib-location>/WEB-INF/sql.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/sql-rt</taglib-uri>
<taglib-location>/WEB-INF/sql-rt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/x</taglib-uri>
<taglib-location>/WEB-INF/x.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/x-rt</taglib-uri>
<taglib-location>/WEB-INF/x-rt.tld</taglib-location>
</taglib>
</jsp-config>
使用任何库,你必须在每个JSP文件中的头部包含标签。
核心标签是最常用的JSTL标签。在JSP页面中引用核心标签库的语法如下:
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core" %>
JSTL格式化标签用来格式化并输出文本、日期、时间、数字。引用格式化标签库的语法如下:
<%@ taglib prefix="fmt"
uri="http://java.sun.com/jsp/jstl/fmt" %>
JSTL SQL标签库提供了与关系型数据库(Oracle,MySQL,SQL Server等等)进行交互的标签。引用SQL标签库的语法如下:
<%@ taglib prefix="sql"
uri="http://java.sun.com/jsp/jstl/sql" %>
JSTL XML标签库提供了创建和操作XML文档的标签。引用XML标签库的语法如下:
<%@ taglib prefix="x"
uri="http://java.sun.com/jsp/jstl/xml" %>
JSTL包含一系列标准函数,大部分是通用的字符串处理函数。引用JSTL函数库的语法如下:
<%@ taglib prefix="fn"
uri="http://java.sun.com/jsp/jstl/functions" %>
IDEA导入jstl1.2常见问题:
The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml
解决方法:https://blog.csdn.net/sinat_34104446/article/details/82846585
第十一节 redirect Ajax Chrome调试JS
sendRedirect和getRequestDispatcher
responese.sendRedirect() (重定向)有两次请求,两个响应
request.getRequestDispatcher() (请求转发)servlet完成任务提供一个响应数据给jsp页面
这两个只能用来控制 JSP 页面。
AJAX
Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。解决浏览器只有跳转才能拿数据的问题。
Ajax的核心是XMLHttpRequest
第十二节 JSON
jackson 阿里巴巴的 fast json
对象转JSON
User.java
public class User {
private String name;
private int age;
private List<String> list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
Main.java
public class Main {
public static void main(String[] args) throws JsonProcessingException {
User user=new User();
user.setName("老王");
user.setAge(28);
//对象转Json
ObjectMapper mapper =new ObjectMapper();
List<String> list=new ArrayList<String>();
list.add("xxx");
list.add("xxx");
list.add("xxx");
list.add("xxx");
list.add("xxx");
list.add("xxx");
user.setList(list);
String userJson=mapper.writeValueAsString(user);
System.out.println(userJson);
}
}
第十三节 javaweb登录验证小demo
dao :data access object
错误:
已经配置好 c3p0 0.9.5.2 和mysql-connector-java 8.0.16
java.lang.ClassNotFoundException: com.mchange.v2.c3p0.ComboPooledDataSource
解决方法:c3p0的jar包放到Tomcat里