Server 服务端 / let 一段代码
硬件 : 高性能计算机 — 个人PC 硬盘?内存?CPU?散热?
软件 : 服务器软件安装使用。 ---- Tomcat 开源免费/应用广泛。
解压!!!! 不建议在中文路径中安装。
建议使用命令窗口启动:
启动:startup.bat 关闭 : shutdown.bat
http://localhost:8080
Oracle 和 Tomcat 出现了端口冲突。
修改Tomcat的端口号
conf —> server.xml
注意: 1、 不适用自带的Tomcat
2、 disable —> Enable
3、 路径点开可以看到bin’目录
Web Project ----> next (需要去新建 web.xml文件)
部署至服务器中 …
静态资源在WebRoot文件夹下!!!!!!!!!!
Hello World!
服务器 : 书写路径去访问服务器资源(静态资源)。
问题?
你所访问的网站,看到的网页都是静态(内容不可变)的吗???
结果:
相同的访问路径,获取到不同的页面展示结果 -----> 网页应该是动态生成的
let 一段代码 : 使用java程序去动态生成网页。
案例: 在网页中展示系统当前时间。 new Date();
Servlet 同样是一个接口 , 实现Servlet接口中的方法即可。
public class FirstServlet implements Servlet {
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
//Servlet的核心实现方法
//request 请求 response 响应
//给用户一个网页 html 内容:系统的当前时间
//设置响应的类型
response.setContentType("text/html");
//获取流对象 传输数据
PrintWriter writer = response.getWriter();
//输出结果
writer.print("");
writer.print("");
writer.print(""
+new Date()+"");
writer.print("");
//释放资源
writer.flush();
}
@Override
public void destroy() {
// 销毁
}
@Override
public ServletConfig getServletConfig() {
// 获取servlet配置信息
return null;
}
@Override
public String getServletInfo() {
// 获取Servlet包含信息
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// 初始化方法
}
}
<servlet>
<servlet-name>firstServletservlet-name>
<servlet-class>com.baizhi.servlet.FirstServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>firstServletservlet-name>
<url-pattern>/firstServleturl-pattern>
servlet-mapping>
http://ip:port/项目名称+url-pattern配置
localhost:8989/Servlet_Day1/firstServlet
1、端口占用 tomcat进程出现了多个
java.net.BindException: Address already in use: JVM_Bind <null>
解决: 1.执行shutdown.bat
2.重启电脑
2、保证服务器中一次只有一个项目
只要有一个项目出错,所有的启动都会报错。
3、404错误 --- 路径错误!!!!
1. 浏览器地址栏写错误
2. 配置信息错误
4、org.xml.sax.SAXParseException;
systemId: jndi:/localhost/Servlet_Day1/WEB-INF/web.xml
Caused by: java.lang.IllegalArgumentException:
Invalid <url-pattern> firstServlet in servlet mapping
web.xml配置错误
5、500服务器内部错误
代码写错了~~~
java.lang.ClassNotFoundException: com.baizshi.servlet.FirstServlet
全限定名称写错了
1、 浏览器的地址栏直接书写访问路径
http://192.168.0.215:8989/Servlet_Day1/firstServlet
2、 超级链接
<a href="http://192.168.0.215:8989/Servlet_Day1/firstServlet">连接</a>
<a href="/Servlet_Day1/firstServlet?user=123">连接</a>
简写:项目名称/资源路径
3、 form表单
<form action="" method="get/post">
</form>
action="书写规则和超级连接 href 一样!!!"
三种方式分为两大类:
get / post 区别 传递数据是否会在地址栏中展示!!!!
get: 地址栏直接书写 / 超级链接 / form 表单的 method=“get”
post: form表单的method=”post“
展示一张表的所有数据在网页
1.展示系统时间 按 yyyy-MM-dd 的格式2.展示商品表中所有的数据,时间也按照上述的格式进行展示。
对象从创建到销毁过程
1、初始化 第一次被请求调用的时候由服务器进行初始化操作
2、销毁 关闭服务器的时候由服务器进行销毁
3、一共被创建了几次??
构造方法只会被执行一次 -----> Servlet是一个单例对象!!!
Servlet中不能定义成员变量!!!!
特殊配置!!!!
服务器启动的时候自动创建初始化Servlet对象
参数加载的启动顺序
<load-on-startup>1load-on-startup>
<servlet>
<servlet-name>firstServletservlet-name>
<servlet-class>com.baizhi.servlet.FirstServletservlet-class>
<load-on-startup>1load-on-startup>
servlet>
1、从页面向服务器发送数据
get / post 两大类发送方式
1、地址栏和超级连接 get方式
localhost:8989/项目/资源?标识=数据值
localhost:8989/项目/资源?key=value
localhost:8989/项目/资源?username=liuyang
注意:地址栏不建议直接书写中文
2、
<form action="xxxx" method="get/post">
<input type="text" name="username"/>
form>
2、Servlet中如何接收数据
String value = request.getParameter(String key);
//接收到用户提交的数据类型只能是String类型
//如果做数据类型的转换 需要判断数据是否为null
//String key : url?key=value 或者 是input标签中 name的属性值
3、如何解决接收数据的乱码问题
同时在浏览器的页面中设置编码格式
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
需要在Tomcat的配置文件中进行修改
<Connector port="8989" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
//在Servlet中进行接收数据的编码设置
request.setCharacterEncoding("UTF-8"); 在接收数据之前书写
get乱码 、 post乱码
java中的数据在浏览器展示的时候发生数据的乱码
两种方式二选一!!!
1、 response.setContentType("text/html;charset=UTF-8");
2、 response.setCharacterEnconding("UTF-8"); 相当于charset=GBK
继承 HttpServlet 类 完成service方法的实现
只关注核心方法的实现,更加强大的功能。
public class MyServlet extends HttpServlet{
//剩下的代码书写 和之前完全没有区别
//只关注核心业务实现方法
public void service(HttpServletRequest request,HttpServletResponse response)
throws IOException,ServletException{
//xxxxx
}
}
注意: 405 错误 ---- 无法寻找对应的方法实现。
HTTP Status 405 - HTTP method GET is not supported by this URL
service 方法声明写错了
将访问路径重新定向(改变),发起了全新的请求访问。
使用: 一般不包含数据的传递!!!!
代码:
response.sendRedirect("跳转的路径");
response.sendRedirect("/Servlet_Day2/login.html");
response.sendRedirect("/Servlet_Day2/bServlet");
表
username varchar2()
password varchar2()
sex varchar2()
city varchar2()
age number(3)
1、 注册页面 (html)
用户名 、 密码 、 性别(单选按钮) 、 城市(下拉菜单) 、 年龄 age
2、 提交注册数据到Servlet中 (RegistServlet)
2.1 接收页面提交数据 数据类型的转换
2.2 调用service业务层 添加方法
2.3 跳转至登陆页面
3、 登陆页面 (html)
提交用户名和密码
4、 登陆的Servlet中 (LoginServlet)
4.1 接收用户提交的数据
4.2 调用Service的查询方法
4.3 判断是否有查询结果
4.4 有结果 跳转至展示所有用户的Servlet中展示数据 (跳转路径)
4.5 没有结果 跳转至登陆页面 再次登陆 (跳转路径)
5、 展示所有用户数据的Servlet
5.1 调用Service方法 查询所有用户数据
5.2 返回展示页面
Service接口{
注册(User user);
登陆(User user);
查询所有()
}
6、****展示所有的页面中再添加一个模糊查询
进行跳转,同时可以进行数据的传递。
跳转的书写方式:
标准:
RequestDispatcher rd = request.getRequestDispatcher("/b");
rd.forward(request, response);
简写:
request.getRequestDispatcher("/b").forward(request,response);
注意:
参数 ---> url-pattern 没有项目名的存在
如何进行数据的传递:
使用request对象完成了数据的传递。 ----> request作用域 域:范围
request.setAttribute(String name,Object value);
Object obj = request.getAttribute(String name);
跳转方式 | 区别 | 使用 |
---|---|---|
redirect 重定向 | 地址栏发生改变,两次请求。 | 跳转,但一般不进行数据的传递 |
forward 请求转发 | 地址栏没有发生改变,一次请求。 | 跳转,进行数据的传递 |
注意: redirect 重定向 可以进行?的数据拼接传递。不能使用request传递数据
注意: 不是所有的Servlet都需要拆分 ! 既有(参数的收集和业务方法的调用),又有(页面的展示)。
会话: 沟通 浏览器和网站的沟通。
追踪:彼此的识别。 网站实际上是识别每一个独立访问的用户。
网站始终记录着每一个用户的访问操作。
http协议不会记录用户的状态。
Cookie 和 Session
//创建cookie对象
Cookie cookie = new Cookie(String name,String value);
cookie.setMaxAge(int s);
存活时间! 秒为单位 s 默认值是负数
正数:代表了存活的秒数
等于0 : 立刻销毁
负数 : 关闭浏览器销毁
//通过相应将cookie对象返回给浏览器
response.addCookie(cookie对象);
//在Servlet中获取Cookie对象
Cookie[] cookies = request.getCookies();
遍历
cookie.getName();
cookie.getValue();
注意:
1、存储的数据量较小 4K
2、不支持存储中文
中文的编解码操作!!!!!
java.net.URLEncoder.encode(“刘洋”, “UTF-8”)
java.net.URLDecoder.decode("%E5%88%98%E6%B4%8B", “UTF-8”)
3、设计缺陷 可以被用户手动禁用!!!!
Session 本身就代表了一次会话。
每一次浏览器发起对于服务器的请求访问,服务器都会创建一个只属于特定浏览器的session对象。
浏览器关闭会话结束,则session改变。
1、一台电脑的多个浏览器访问,则服务器会创建几个session对象?
每一个浏览器一个!!
2、同一浏览器开启多个子窗口
公用一个session对象!!!
注意:只要浏览器不发生改变,则session对象不发生改变
浏览器改变(关闭再次开启,电脑中的不同品牌浏览器)
使用session对象
获取session对象
HttpSession session = request.getSession(); 默认true
HttpSession session = request.getSession(true/false);
true:如果服务器中没有当前浏览器对应的session对象则创建。
false:如果服务器中没有当前浏览器对应的session对象不进行创建。
false:只会使用已经存在的session对象,没有就不用了!!!!!
session作用域
session.setAttribute(String name,Object value);
Object obj = session.getAttribute(String name);
作用域的范围:
reuqest作用域: 一次请求,请求结束数据失效。
session作用域: 一次会话(一个浏览器),会话没有结束session对象中的数据一直有效。
session的生命周期
创建:用户对于服务器发起第一次请求,且执行request.getSession(true);
销毁:timeout 超时属性
从最后一次操作session对象之后,30分钟无操作,则销毁session对象。
<session-config>
<session-timeout>30session-timeout>
session-config>
为什么每一次都能找到自己的session?
每一个session对象都会有一个Cookie唯一标识
name-value JSESSIONID–唯一标识(8ED632D61669F56681FCD998146962C0)
登陆的Servlet
//接收数据
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
//调用业务
if(username.equals("liuyang")&&password.equals("123456")){
//确认登陆成功 且还未进行跳转 存入登陆的标识
HttpSession session = request.getSession();
session.setAttribute("flag", "loginSuccess");
//跳转至展示Servlet
response.sendRedirect("/Servlet_Day4/showAll");
}else{
//跳转回登陆页面
response.sendRedirect("/Servlet_Day4/login.html");
}
强制登陆的判断
//强制登陆的标识判断
HttpSession session = request.getSession();
String flag = (String) session.getAttribute("flag");
System.out.println("标志位:"+flag);
if(flag!=null){
//相等说明执行过登陆操作
//业务
System.out.println("-------展示数据---刘洋到此一游!!!!!!!!----");
}else{
//跳转至登陆页面
response.sendRedirect("/Servlet_Day4/login.html");
}
验证码
防止恶意访问 、 用Servlet去生成图片。
ServletContext:一个应用程序 (唯一所有访问网站的用户可以共有同一个ServletContex作用域t对象)
应用发生改变:服务器关闭 项目的重新部署…
set/getAttribute(); 向作用域中进行数据的存储。
作用域 | 范围 | 改变 |
---|---|---|
Request | 一次请求 | 每一次新的请求就会改变 |
Session | 一个会话 | 会话改变(浏览器发生改变) |
ServletContext | 一个应用 | 重启服务器或者重新部署项目 |
连接的频繁创建销毁浪费资源,选择使用连接池。
Database Connection Pool (DBCP)所有连接对象的创建,销毁,调用都由连接池决定。
需要在服务器中进行连接池的配置。
1、conf --> context.xml
<Resource name="jdbc/myoracle" JNDI规范 : java命名规范
auth="Container" 类型:容器
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
username="hr"
password="hr"
maxActive="20" 最大连接数
maxIdle="10" 最大空闲
minIdle="5" 最小空闲
maxWait="-1"/> 等待
2、配置 web.xml
<resource-ref>
<description>Oracle Datasource exampledescription>
<res-ref-name>jdbc/myoracleres-ref-name>
<res-type>javax.sql.DataSourceres-type>
<res-auth>Containerres-auth>
resource-ref>
3.引入数据库驱动jar
tomcat --- lib
4.使用 代码
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
注意: 连接由服务进行创建,需要数据库驱动jar包。
减少了Servlet中的代码冗余。
实现Filter接口
@Override
public void destroy() {
//销毁方法
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//冗余代码
System.out.println("------Filter-------");
//请求没有从过滤器中出去 放行请求 让请求继续向后执行
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
//初始化
}
<filter>
<filter-name>filterfilter-name>
<filter-class>com.baizhi.filter.MyFilterfilter-class>
filter>
<filter-mapping>
<filter-name>filterfilter-name>
<url-pattern>/testurl-pattern>
filter-mapping>
1、具体的某一个Servlet路径
<url-pattern>/testurl-pattern>
2、项目中的所有Servlet
/*
3、有选择的过滤
Servlet: 对Servlet的url-pattern进行分类 /filter/a /filter/b
filter : /filter/*
开发步骤
1、实现Filter接口
完成核心方法的实现doFilter
1、冗余代码 2、放行请求
2、配置web.xml
url-pattern 过滤的Servlet的路径
创建:随着服务启动自动进行初始化操作
销毁:随着服务关闭自动进行销毁操作
单例模式
先执行哪个过滤器?
由web.xml中的配置顺序决定,先执行配置靠前的,再执行配置靠后的。
1、 doFilter 方法中 request/response
获取session对象以及进行跳转时,需要强制类型转换。
ServletRequest —> 转 —> HttpServletRequest
2、过滤器默认不会过滤forward跳转方式
<filter>
<filter-name>filterfilter-name>
<filter-class>com.baizhi.filter.MyFilterfilter-class>
filter>
<filter-mapping>
<filter-name>filterfilter-name>
<url-pattern>/*url-pattern>
<dispatcher>REQUESTdispatcher>
<dispatcher>FORWARDdispatcher>
filter-mapping>
监听Servlet中作用域对象的创建,销毁,数据的改变。
监听器接口:一共有六个
Listener三个 : 监听作用域对象的创建和销毁
AttributeListener三个:监听作用域对象中数据的添加、删除、替换。
细节:
1、作用域删除数据 removeAttribute(String name);
2、session的手动销毁 session.invalidate();
t/response
获取session对象以及进行跳转时,需要强制类型转换。
ServletRequest —> 转 —> HttpServletRequest
2、过滤器默认不会过滤forward跳转方式
<filter>
<filter-name>filterfilter-name>
<filter-class>com.baizhi.filter.MyFilterfilter-class>
filter>
<filter-mapping>
<filter-name>filterfilter-name>
<url-pattern>/*url-pattern>
<dispatcher>REQUESTdispatcher>
<dispatcher>FORWARDdispatcher>
filter-mapping>
监听Servlet中作用域对象的创建,销毁,数据的改变。
监听器接口:一共有六个
Listener三个 : 监听作用域对象的创建和销毁
AttributeListener三个:监听作用域对象中数据的添加、删除、替换。
细节:
1、作用域删除数据 removeAttribute(String name);
2、session的手动销毁 session.invalidate();
3、短时间内重启服务器 session对象不会销毁。 tomcat6以上版本