本文是主要介绍了Java后端的基础,包括环境安装、Servlet、JSP、Mysql等
环境搭建
基础概念
以下三者从上到下包含关系:JDK包括JRE,JRE包括JVM。
JVM
跨平台,完成对Window,linux,iOS等不同系统的差异的封装。其实包括对齐、字节序、大小端等问题
虚拟机不止一种,IBM,SUN公司的虚拟机,SUN公司出了JVM规范,不同公司都可以实现。
*.java
编译成*.class
给虚拟机执行。
Java EE:企业版
Java ME:微版
Java SE:
安装
- 下载:oracle官网下载JDK最新为Java 8u141
- 安装:点击安装,注意其中会提示jre的安装目录,完成安装
- 设置环境变量:
JAVA_HOME:
path
- 测试:cmd中java -version 或者java
hello world
- 类名与文件名一致
- .java文件,由javac编译生成.class文件,再由java命令+类名进行运行
servlet
HTTP协议
- 互联网3大基石:http:传输数据;url:定位数据;html:显示数据
- 超文本传输协议,http消息请求、相应,一问一答;
- 浏览器信息交换过程
建立连接
发送请求信息
服务器回送响应信息
关闭连接
- http1.1支持连续连接,一次连接可以发送多次请求。
需要提前声明
- http是一种无状态协议
连接之间不相关,服务器端可以去记录连接信息,但协议本身不提供。
连接:服务器端叫session(会话),浏览器端较cookie
- httpwatch,IE与火狐中可用,可以查看http
firebug,火狐
请求基本格式:
响应格式
servlet运行过程
servlet运行过程
- 浏览器发送url请求到服务器
- 服务器根据请求的url,去调用相应的servlet1类
- 通过servlet1中的打印流对象,将生成的html数据输出给服务器
- 服务器根据servlet生成的数据再输出给客户端浏览器。
- 浏览器根据服务器传回的html,显示数据。
要点
helloworld
<servlet>
<servlet-name>one</servlet-name>
<servlet-class>com.bjsxt.servlet.FirstServlet<servlet-class>
</servlet>
1对多关系
<servlet-mapping>
<servlet-name>one</servlet-name>
<url-pattern>/111</url-pattern>
<url-pattern>/222</url-pattern>
</servlet-mapping>
- 安装tomcat
tomcat去运行了自己写的Java程序。
在tomcat中可以手动发布,也可以自动发布
servlet配置详解
web建立
servlet
- extends HttpServlet
- 重写service
- 配置web.xml:servlet,servlet-mapping
手动发布
自动发布
Myeclipse集成tomcat
- server配置
- 项目发布
- 项目path修改:properties->myelipse->web
tomcat中server.xml配置
- port:80为默认端口
- Host:
<Context path="/uuu" docBase="D:\workspace\SecondServlet\WebRoot" reloadable="true" />
,docBase修改后不再复制到webapps虾,reloadable=true以后,在myeclipse修改内容后,自动发布
servlet内部执行过程
- 载入:第一次请求的时候被初始化,只一遍
- 初始化:调用init方法,只一遍
- 执行:
每个请求,new一个新的线程,调用一遍service->super.service->doGet/doPost
不要在servlet中设计成员变量(多请求线程会共享,发生资源冲突)
doGet/doPost常见异常:Http Status 405-HTTP method POST(GET) is notsupported by this URL:增加doGet或doPost即可。
- 销毁
卸载前调用的destroy方法,子类servlet一般不需要覆盖这个方法。
- 非分布式情况下,服务器只用一个servlet实例。
源码分析
- this关键字指向对象本身
- super关键字指向父类对象
- 当子类中调用父类对象中的函数,而父类函数中的函数再调用子类覆盖的函数时,此时调用的是子类覆盖后的函数。
- 注意:在同一个文件中写类时,使用的类,不能写protected、private、public
web.xml配置
- default
servlet时可以不配servlet-mapping,load-on-startup配置为1,用于写
- welcome-file-list
index.html:当访问文件夹时,显示此文件,若没有,看配置,或者返回404,或者显示文件夹内容,不包括WEB-INF,META-INF,注意index.html不能放在web-inf文件夹中.
注意:
服务器与浏览器缓存
当发现改的代码不管用,可能是浏览器缓存,也可能是服务器缓存,可以重新刷新、删除缓存来实现。
servlet中重要对象的使用
HttpServletRequest对象
HttpServletResponse对象
- 状态行,响应头,响应实体
- 状态行服务器自动生成,无函数
- 响应头的函数
setHeader
addHeader
- 响应实体
getWriter:文本
getOutputStream:二进制,下载、视频等
请求转发与重定向
重定向
- HttpServletResponse的sendRedirect(URL)的重定向,状态码302
- 由重定向可以完成服务器的跳转。
- 地址栏改变
- 整个过程2次请求
- 转发之后的语句依然会被执行,一般后边紧跟return
请求转发
-
HttpServletRequest的getRequestDispatcher("index.html").forward(req, resp);
-
地址栏不变,服务器内部的
-
整个过程1次请求
-
转发之后的语句依然会被执行,一般后边紧跟return
-
多个servlet属于一个请求,公用同一个request对象,可以通过resquest作用域来共享一些信息。
setAttribute("a",new Date())
getAttribute("a")
removeAttribute("a")
getAttibuteNames()返回枚举,遍历
path/的总结
- 从浏览器跳转,/ 代表localhost/
- 从服务器跳转 / 代表localhost/uuu/,web应用根目录
session与cookie
差异
- session:服务器端
适合保存大量的数据
安全
效率高
session跟踪机制中需要cookie来保存传递sessionID
- cookie:客户端
不适合保存大量的数据
不安全
效率低
取得
req.getSession();
作用域
被属于同一个会话的请求共享:同一浏览器,同一服务器
session作用域比request范围大
方法
session.getId()
session.setMaxInactiveInterval(6)session的最大空闲时间。
session.invalidate()强制session失效
cookie
- 将http状态保存在客户端的技术
- 不是服务器直接读取本地的cookie,是浏览器读取cookie,而服务器读取浏览器发出的名为cookie的请求头信息
- 函数
- 取得
Cookie cookie= new Cookie("uname", "dabao");
- 方法
cookie.setMaxAge(3600*24)
setName
setValue
getName
getValue
- 响应信息中添加Cookie
response.addCookie(cookie)
- 取得客户端发来的Cookie
request.getCookie
返回Cookie[]类型的数组,再用getName,getValue来访问。
servletConfig
介绍
函数
- 取得
ServletConfig sc=this.getServletConfig();
- sc.getInitParameter("aaa");返回名为aaa的参数的值
- sc.getServletName();取得所属servlet的名字
- sc.getInitParameterNames();返回所有参数名的美剧
感触
有些像.ini文件,不过写在web.xml中,用于向服务器配置一些数据。
servletContext
介绍
- 一个web应用只有一个ServletContext对象。所有的Servlet都共享着一个ServletContext对象,又称为Application对象
- 作用域:
空间最广,被所有Servlet共享
时间最长,从Web应用被加载到被卸载都有效。
用法
- 读取web.xml中的参数
- setAttribute/getAttribute/removeAttribute
- 获取文件绝对路径:getRealPath("1.jsp");
- 用预获取目录下所有目录和文件的路径,返回set类型
getResousePaths("/picture");
- 用于获取web应用中的资源:getResourceAsStream("/1.properties");
注意
request、session、context的差同
- 相同之处:他们都有map来存储键值对。
- 不同,他们的作用域不同:request基于一次的请求与相应,session基于一次连接,context则可以认为是全局。cookie可以认为是一种客户端的认证,当session关闭的时候,可以通过cookie来认证客户。
中文问题解决
- post方式提交的数据,采用
request.setCharacterEncoding("gbk");
- get方式提交的数据
在server.xml中元素<connector>
中增加属性,useBodyEncodingForURI="true"
- 通用方法
new String(str.getBytes("iso8859-1"), "gbk")
MyServer实现
- 由MyServer创建监听socket
- accept到请求后,创建新线程并将监听到的socket传递给处理线程
- 处理线程实现Runnable,在实现类中,获取的输入输出流(InputStream与OutputStream),输入输出流用read与write来实现传输。
- IO操作都放在try、catch中并且有finally中实现输入输出流的关闭。
servlet实战
现在问题:
- 网页有2种请求方式:
- 直接请求html的网页;
- 访问相应的servlet,通过servlet的代码来传递网页信息。
为了实现前后端分离,应该使用1
- 跳转2种方式
- 请求转发
- 重定向
都使用。
- html如何与servlet程序关联?
此处在表单那一节有所记录
- 最难一个:如何动态刷新登录不成功的提示?
此处需考虑::在表单的action中录入对应的servlet即可完成对应
- 账户与密码的存储
存储在session中,通过设置session的property
问题
- web.xml的建立
- html背景图片的拉伸
- margin/position所对应的标准
- 字符的空格
- JS与后台服务交互的过程如何实现?
差异
- 老师用后台写的页面而我是自己画的html
老师这种不适合后台与前端的分离,而通过session的setAttribute达到了动态显示的目的。而我的始终没有实现当登录不成功后的动态显示。
- 老师在存储数据时使用的是session而我使用的是cookie
属于题目问题,但用session时新建User类来存储数据不错。
JSP
为什么需要JSP
- Servlet
优点:逻辑处理方便
缺点:页面表现麻烦
- Jsp
优点:
缺点:
- 互补
jsp + servlet + javabean
学习ssh后,可以采用ssh框架。
Jsp本质
Jsp是一种动态网页技术
动态网页技术:
动态生成网页技术,而不是由动态效果的网页
常见动态网页技术:jsp,asp,php
Jsp就是servlet所以jsp也是java类,通过jsp引擎把jsp转化成servlet
jsp ~ java+html
过程
- web.xml:
*.jsp由org.apache.jasper.servlet.JspServlet处理
- JspServlet将Jsp变成.java
在tomcat/work下有源代码。
JSP语法
JSP编译器指令
- page
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import"java.util.,java.io."%>
<%@ page errorPage="error.jsp"%>
- include
静态导入:<% include file="相对位置"%>
动态导入:<jsp:include page="included.jsp"></jsp:include>
- 注释
浏览器不可见:<!-- -->
java编译器注释://
JSP引擎注释<%-- --%>
JSP脚本代码
- Java 脚本段:在service代码中
<% %>
- 表达式段:相当于out.print(dd+3)
<%=dd+3%>
- 声明段:相当于在类中声 明变量
<%!
int h=3;
void test(){
System.out.print(h);
}
%>
jsp内置对象
response不建议使用,使用out
<%@ page session="false" %>
访问量大要关掉session
application.setAttribute
可以使用application来实现JSP与servlet项目的通用。
web.xml中的初始化.与servletConfig对象相同。
标签
动态包含:<jsp:include page='<%=request.getParameter("includePage")%>'></jsp.include>
传参:<jsp:param value="1234" name="kk">
<jsp:forward page=4.jsp">
forward之后的代码不能执行
- useBean
- getProperty
- setProperty
作用域寻找顺序
pageContext/request/session/application
练习
- 19:40
实战总结
html与jsp差异:动态网页与静态网页的区别
一开始我的实现使用html来画页面,但对于显示登录失败提示,无法实现;而又JSP,可以使用全局的(servletContext=application)、会话的(session)、请求的(request)、页面的pageContext来实现数据的传递。
本例在实现错误提示时,使用的是请求转发技术,所以使用基于请求的request.setAttribute来实现数据的传递。
jsp与servlet的差异
jsp是通过jsp引擎,将jsp代码转换为servlet代码的技术。
与servelt能沟通数据,就是基于上述的各作用域的内置对象:基于全局的servletContext=applicaiton,会话的session(request.getSession),请求的request(HttpRequest),还有一个jsp特别的pageContext
session与cookie差异
创建不同
session为tomcat服务器创建(getSession时),而cookie由servlet自己创建并通过response返送给浏览器。
作用域相同
作用域应该相同,应该都是基于会话的
数据结构不同
session本质是map
cookie本质就是name与value
几个对象的使用:各作用域数据传输
基于全局:
servletContext=applicaitong,全局数据区
基于会话:
session,应该说是基于连接的,只要连接不变,多个servlet可以共享本会话的数据。
基于请求:
request,通过请求转发可以在多个servlet中传递数据
以上本质都是map,全局可以有很多会话,会话可以有很多请求。
配置文件
servletConfig,就是用事先配置的参数对服务运行进行配置
pageContex
应该是基于会话的,只不过它封装了各种数据
MVC初感
MySQL
安装
- 下载
首先去官网www.mysql.com下载最新版本,我的是5.7.13zip版,就是免安装,可以直接解压到需要的地方。
2.环境变量的配置:
计算机-》右键-》属性-》高级系统设置-》高级-》环境变量 在PATH里面加入解压的地方,比如我是E盘,就加入d:\mysql\bin
3.在解压的地方D:\mysql新建一个my.ini文件,添加如下内容:
[client]
port=3306
default-character-set=gb2312
[mysqld]
port=3306
character_set_server=gb2312
4.开始-》运行-》cmd。注意此步骤需要管理员权限才可,否则会denied
首先 cd D:\mysql\bin
命令:mysqld --initialize #直接初始化mysql,生成data文件夹中的文件。
命令:mysqld -install #安装mysql
命令:net start mysql #启动服务器
5、设置root密码
此时用mysql -uroot -p登录时,不知道密码,按以下步骤设置密码。
1)编辑解压目录下的 my.ini文件,在[mysqld]这个条目下加入
skip-grant-tables
保存退出后重启mysql
停止:输入 net stop mysql
启动:输入 net start mysql
这时候在cmd里面输入mysql -u root -p就可以不用密码登录了,出现password:的时候直接回车可以进入。
2)进入mysql 数据库:
use mysql;
显示:
Database changed
3)给root用户设置新密码,在命令行输入:
mysql>(版本5.7)update user set authentication_string=password('123qwe') where user='root' and Host = 'localhost';
显示:
Query OK, 1 rows affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
4)刷新数据库
mysql> flush privileges;
显示:
Query OK, 0 rows affected (0.00 sec)
5)退出mysql:
mysql> quit
6)修改my.ini
改好之后,再修改一下my.ini这个文件,把我们刚才加入的"skip-grant-tables"这行删除,保存退出再重启mysql就可以了。
修改完毕。重启mysql服务。
登录:mysql -uroot -p123qwe
mysql就可以连接了
7)mysql> alter user 'root'@'localhost' identified by '123';
数据类型
- int
- double
- char
- vchar
- long:4g
- datetime
小知识
? 帮助
. mysql.sql; (接脚本)
工具
mysql-administrator
管理
- show databases; 所有的数据库
- show tables; 数据库下的表
- desc dept; 查看表的字段
差异
数据类型
分页技术
- oracle:row number方式,三层select
- select * from dept order by deptno limit 3,2;从第3条后取2条
自动递增字段
- oracle:sequese, nextValue;
- mysql:auto_increment字段,插入时直接时候null代表该字段,或者通过指定字段不插入该字段
日期处理
- orcle: select sysdate from due;
to_char
- mysql:select now();
select date_format(now(), '%Y-%m-%d %h:%i:%s');
Tree实战
bbs节点数据结构:父指针,第一个子节点指针,兄弟指针(斐波那列堆)。父,所有子节点
遍历形成树
树的遍历输出
JDBC
JDBC简介
- Java Database Connectiy
- ODBC:微软平台
ADO.NET
- JDBC:Java平台
Hibernate真正实现了底层封装,微小差异
JDBC编程步骤
- Load the driver
- connect to the Database
- Execute the SQL
- Retrieve the result data
- Show the result data
- close
Load the driver
class path:系统与工程
- build path
- Class.forName("oracle.jdbc.driver.OracleDriverw")
new oracle.jdbc.driver.OracleDriver
- 实例化时自动向DriverManager注册,不需显示调用DriverManager.registerDriver方法
Connect
Connect conn = DiverManager.getConnection("jdbc:orcle:thin:@192.168.0.1:1521:SXT","user","password")
连接串
Execute the sql
- Statement st=conn.createStatement();
- ResultSet rs = st.executeQuery("select * from dept");
retrive the result data
- while(rs.next()){}
- rs.getString("deptno")
rs.getInt("deptno");deptno:字段名
rs.getBoolen等等
关闭
rs.close();
st.close();
conn.close();
try catch catch finnally中关闭【1】
rs.close();也抛异常,需要在finnally中try也catch
感概:
执行一条需要new这么多对象,不如odbc
insert的简单方式PreparedStatement【2】
与odbc中的prepare类似
?占位符,然后调用setInt(1, deptno);等去塞数。
调用过程callableStatement
{call p(?,?,?,?)}
需要先procedure,然后调用
批处理:addBatch()
transaction:事物【3】
conn.setAutoCommit(false);
conn.commit();
conn.rollBack();
默认情况下,执行一条语句,立即提交。这个比odbc好一些。
可移动的结果集
- oracl在获取时可能需要
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
但经试验mysql现在5.7.19版本,不需要,直接使用conn.createStatement();
- rs.next()
- rs.last(),指向最后一条
- rs.getInt(1); rs.getString(1);将第一个字段以Int,String类型拿出。
- rs.isLast()是否最后一条
- rs.isAfterLast()是否指向最后一条的后边
- rs.previous():前滚
- rs.absolute(4):指向第4条记录
可更新的结果集[*]
-
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATEABLE);
-
增
rs.moveToInsertRow()
rs.update(1,99);
rs.insertRow();
-
删
rs.absolute(3);
rs.deleteRow();
-
改
rs.next();
rs.updateString(2, "aaaa");
rs.updateRow();
DataSource【4】
DriverManager的替代
J2EE应用结合在一起,是一种数据源,拿到与数据库的链接
支持连接池
支持分布式
RowSet
新的ResultSet,从ResultRet继承
支持断开的结果集,处理期间,可以断开与数据库连接。
支持JavaBean标准,支持图形化接口