第一天servlet
一、第一个JavaWeb项目
1.1编写一个java类继承HttpServlet方法
//myServlet.java
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class myServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("this is my first servlet.");
}
}
1.2配置web.xml
<!-- 配置servlet路径 -->
<servlet>
<servlet-name>my</servlet-name>
<servlet-class>com.servlet.myServlet</servlet-class>
</servlet>
<!-- 配置访问方式 -->
<servlet-mapping>
<servlet-name>my</servlet-name>
<url-pattern>/my</url-pattern>
</servlet-mapping>
浏览器访问:
http://localhost:8000/test/my
浏览器显示:
this is my first servlet.
二、request和response对象
2.1servlet的生命周期
//ServletLeft.java
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* Servlet的生命周期:
* 1、从第一次调用到服务器关闭。
* 2、如果Servlet在web.xml中配置了load-on-startup,生命周期为 从服务器启动到服务器关闭
* 3、注意: * init方法是对Servlet进行初始化的一个方法,会在Servlet第一次 加载进行存储时执行
* 4、destory方法是在servlet被销毁时执行,也就服务器关闭时
*
*/
public class ServletLeft extends HttpServlet{
//初始化方法,在servlet第一次加载内容时被调用
@Override
public void init() throws ServletException {
System.out.println("servlet初始化完成");
}
//service方法,浏览器请求时被调用
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service被调用");
}
//销毁方法,服务器关闭时调用
@Override
public void destroy() {
System.out.println("servlet被销毁");
}
}
<!--web.xml-->
<!-- 配置servlet路径 -->
<servlet>
<servlet-name>lift</servlet-name>
<servlet-class>com.servlet.ServletLeft</servlet-class>
</servlet>
<!-- 配置访问方式 -->
<servlet-mapping>
<servlet-name>lift</servlet-name>
<url-pattern>/lift</url-pattern>
</servlet-mapping>
控制台:
servlet初始化完成-------浏览器第一次请求时被调用
service被调用-----------浏览器每次请求调用
service被调用-----------浏览器每次请求调用
service被调用-----------浏览器每次请求调用
servlet被销毁-----------服务器关闭调用
<!--加上次标签则在服务器启动就调用-->
<load-on-startup>1</load-on-startup>
<!-- 配置servlet路径 -->
<servlet>
<servlet-name>lift</servlet-name>
<servlet-class>com.servlet.ServletLeft</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置访问方式 -->
<servlet-mapping>
<servlet-name>lift</servlet-name>
<url-pattern>/lift</url-pattern>
</servlet-mapping>
2.2service方法和doGet方法和doPost方法的使用和区别
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* Service方法和doGet方法和doPost方法的区别
* Service方法:
* 可以处理get/post方式的请求,如果servlet中有Service方法,会优先调用service方法对请求进行处理。
* doGet方法:
* 处理get方式的请求
* doPost方法:
* 处理post方式的请求
* 注意:
* 如果在覆写的service方法中调用了父类的service方法(super.service(arg0, arg1)),
* 则service方法处理完后,会再次根据请求方式响应的doGet和doPost方法执行。所以,一般情况下
* 我们是不在覆写的service中调用父类的service方法的,避免出现405错误。
*/
public class ServletMethod extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是service方法");
super.service(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是post方法");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是get方法");
}
}
2.3Servlet的常见错误:
-
404错误:资源未找到
-
原因一:在请求地址中的servlet的别名书写错误。
-
原因二:虚拟项目名称拼写错误
-
500错误:内部服务器错误
-
错误一:
-
java.lang.ClassNotFoundException: com.bjsxt.servlet.ServletMothod
-
解决:
-
在web.xml中校验servlet类的全限定路径是否拼写错误。
-
错误二:
-
因为service方法体的代码执行错误导致
-
解决:
-
根据错误提示对service方法体中的代码进行错误更改。
-
405错误:请求方式不支持
-
原因:
-
请求方式和servlet中的方法不匹配所造成的。
-
解决:
-
尽量使用service方法进行请求处理,并且不要再service方法中调用父类的service。
2.4request对象的介绍和获取请求头信息
作用:request对象中封存了当前请求的所有请求信息
使用:
获取请求头数据
获取请求行数据
获取用户数据
注意:
如果要获取的请求数据不存在,不会报错,返回null。
request对象由tomcat服务器创建,并作为实参传递给处理请求的servlet的service方法。
2.4.1获取请求头数据
<!--index.jsp-->
<body>
<form action="request" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
public class RequestServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求头数据
//获取请求方式
String method = req.getMethod();
System.out.println("请求方式:"+method);
//获取请求URL+URI
StringBuffer url = req.getRequestURL();
System.out.println("url地址:"+url);
String uri = req.getRequestURI();
System.out.println("uri地址:"+uri);
//获取协议
String h = req.getScheme();
System.out.println("网络协议:"+h);
}
}
浏览器:
http://localhost:8000/test/request
控制台:
请求方式:GET
url地址:http://localhost:8000/test/request
uri地址:/test/request
网络协议:http
浏览器:
http://localhost:8000/test/index.jsp
控制台:
请求方式:POST
url地址:http://localhost:8000/test/request
uri地址:/test/request
网络协议:http
2.4.2获取请求行数据
public class RequestServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求行数据
//获取指定的请求行信息
String agent = req.getHeader("user-agent");
System.out.println("用户代理:"+agent);
String host = req.getHeader("host");
System.out.println("host:"+host);
System.out.println("-----------------------------------");
//获取所有请求行的键的枚举
Enumeration e = req.getHeaderNames();
while(e.hasMoreElements()) {
String name = (String)e.nextElement();
String value2=req.getHeader(name);
System.out.println(name+":"+value2);
}
}
}
浏览器:
http://localhost:8000/test/request
控制台:
用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
host:localhost:8000
-----------------------------------
host:localhost:8000
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
accept-encoding:gzip, deflate
connection:keep-alive
cookie:JSESSIONID=DC6B2BD41074E8A4BBF6605A93A80115
upgrade-insecure-requests:1
2.4.3获取用户数据
<body>
<form action="request" method="post">
用户名:<input type="text" name="username"><br />
密码:<input type="password" name="password"><br />
爱好:<br />
<input type="checkbox" name="hobbys" value="sing"/>唱歌<br />
<input type="checkbox" name="hobbys" value="dance"/>跳舞<br />
<input type="checkbox" name="hobbys" value="swim"/>游泳<br />
<input type="submit" value="登录">
</form>
</body>
public class RequestServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户数据
String name=req.getParameter("username");
String pwd=req.getParameter("password");
System.out.println("用户名:"+name);
System.out.println("密码:"+pwd);
//获取所有的用户请求数据的键的枚举集合---req.getParameterNames()
String[] hobbys=req.getParameterValues("hobbys");
System.out.println("爱好:");
if(hobbys!=null){
for(String hobby:hobbys){
System.out.print(hobby+" ");
}
}
}
}
浏览器:
http://localhost:8000/test/index.jsp
填入参数提交
控制台:
用户名:zhangsan
密码:123
爱好:
sing dance swim
2.5response对象学习
Respone对象学习:
作用:
用来响应数据到浏览器的一个对象
使用:
1.设置响应头
2.设置响应状态
3.设置响应实体
4.设置响应编码格式:
2.5.1设置响应头
public class ResponseServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应头
//setHeader会覆盖同名对象
resp.setHeader("phone", "MI");
resp.setHeader("phone", "HUAWEI");
//addHeader不会覆盖同名对象
resp.addHeader("laptop", "MAC");
resp.addHeader("laptop", "ASUS");
}
}
2.5.2设置响应状态码
//设置响应状态码
resp.sendError(404,"this Method is not supported");
2.5.3设置响应实体
//设置响应实体
resp.getWriter().write("<h1>response响应实体</h1>");
2.5.4设置响应编码格式
//设置响应编码格式
//方法一:
resp.setHeader("content-type", "text/html;charset=utf-8");
//方法二:推荐使用
resp.setContentType("text/html;charset=utf-8");
//其他格式
//plain:普通文本
resp.setContentType("text/plain;charset=utf-8");
//xml
resp.setContentType("text/xml;charset=utf-8");
//html
resp.setContentType("text/html;charset=utf-8");
例子:
public class ResponseServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应编码格式
//resp.setHeader("content-type", "text/html;charset=utf-8");
resp.setContentType("text/html;charset=utf-8");
//设置响应实体
resp.getWriter().write("<h1>response响应实体</h1>");
}
}
三.Servlet转发和重定向
3.1servlet登录练习
##创建用户表
create table t_user(
uid int(10) not null auto_increment,
uname varchar(100) not null,
pwd varchar(100) not null,
primary key(uid)
)
##添加测试数据
insert into t_user values(default,'zhangsan','123');
insert into t_user values(default,'lisi','456');
select * from t_user
//登录页com.zh.servlet
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PageServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
// 处理请求
// 响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<form action='login' method='get'>");
resp.getWriter().write("用户名:<input type='text' name='uname' value=''/><br/>");
resp.getWriter().write("密码:<input type='password' name='pwd' value=''/><br/>");
resp.getWriter().write("<input type='submit' value='登录'/><br/>");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
//登录验证页com.zh.servlet
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
resp.getWriter().write("登录成功");
}else {
resp.getWriter().write("登录失败");
}
}
}
//模型层 com.zh.model
package com.zh.model;
public class User {
private int uid;
private String uname;
private String pwd;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User [uid=" + uid + ", uname=" + uname + ", pwd=" + pwd + "]";
}
}
//业务层接口com.zh.service
package com.zh.service;
import com.zh.model.User;
public interface LoginService {
//校验用户登录信息
public User CheckLoginService(String uname,String pwd);
}
//业务层实现com.zh.service.impl
package com.zh.service.impl;
import com.zh.dao.LoginDao;
import com.zh.dao.impl.LoginDaoImpl;
import com.zh.model.User;
import com.zh.service.LoginService;
public class LoginServiceImpl implements LoginService{
//创建Dao层对象
LoginDao ld = new LoginDaoImpl();
@Override
//校验用户登录信息
public User CheckLoginService(String uname, String pwd) {
return ld.checkLoginDao(uname, pwd);
}
}
//持久层com.zh.dao接口
package com.zh.dao;
import com.zh.model.User;
public interface LoginDao {
//根据用户名和密码获取用户信息
public User checkLoginDao(String uname,String pwd);
}
//持久层实现com.zh.dao.impl
package com.zh.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.zh.dao.LoginDao;
import com.zh.model.User;
public class LoginDaoImpl implements LoginDao{
//根据用户名和密码获取用户信息
@Override
public User checkLoginDao(String uname, String pwd) {
//声明Jdbc对象
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//声明数据存储对象
User u = null;
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");
//创建Sql命令
String sql="select * from t_user where uname=? and pwd=?";
//创建Sql命令对象
ps=conn.prepareStatement(sql);
//给占位符赋值
ps.setString(1, uname);
ps.setString(2, pwd);
//执行
rs=ps.executeQuery();
//遍历执行结果
while(rs.next()){
u=new User();
u.setUid(rs.getInt("uid"));
u.setUname(rs.getString("uname"));
u.setPwd(rs.getString("pwd"));
}
//关闭资源
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return u;
}
}
存在问题:
1.登录成功应该跳到成功页面
2.登录失败应该换回登录页面
3.2请求乱码问题解决和Servlet流程总结
请求中文乱码解决:
1、使用String进行数据重新编码
uname=new String(uname.getBytes("iso8859-1"),"utf-8");
2、使用公共配置
get方式:
步骤一:req.setCharacterEncoding("utf-8");
步骤二:在tomcat的目录下的conf目录中修改server.xml文件:在Connector标签中增加属性 useBodyEncodingForURI="true"
post方式:
req.setCharacterEncoding("utf-8");
控制台
??:123
//使用String进行数据重新编码:用于重要数据编码
uname=new String(uname.getBytes("iso8859-1"),"utf-8");
//post方式
req.setCharacterEncoding("utf-8");
//get方式第一步
req.setCharacterEncoding("utf-8");
<!--get方式第二步server.xml-->
<Connector port="8089" protocol="AJP/1.3" redirectPort="8443" useBodyEncodingForURI="true"/>
3.3Servlet流程总结:
浏览器发起请求到服务器(请求)
服务器接受浏览器的请求,进行解析,创建request对象存储请求数据
服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法
servlet的方法执行进行请求处理
- 设置请求编码格式
- 设置响应编码格式
- 获取请求信息
- 处理请求信息
- //创建业务层对象
- //调用业务层对象的方法
- //响应处理结果
3.4servlet学习-请求转发
请求转发学习:
-
**作用:**实现多个servlet联动操作处理请求,这样避免代码冗余,让servlet的职责更加明确。
-
**使用:**`req.getRequestDispatcher("要转发的地址").forward(req, resp);`
-
**地址:**相对路径,直接书写servlet的别名即可。
-
**特点:** **一次请求**,**浏览器地址栏信息不改变**。
-
**注意:**请求转发后直接`return`结束即可。
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
resp.getWriter().write("登录成功");
}else {
//登录失败请求转发
req.getRequestDispatcher("page").forward(req, resp);
System.out.println("哈哈");
}
}
}
控制台:
zs:123
哈哈
分析:请求转发相当于调用方法下面的内容会执行
解决:使用return
结束
req.getRequestDispatcher("page").forward(req, resp);
return;
3.5servlet学习-request对象的作用域
- **问题:**使用请求转发后,不同的 Servlet 之间怎么进行数据的共享呢?或者说数据怎么从一个 servlet 流转给另外一个 Servlet 呢?
- **解决:**使用 request 对象的作用域
-
使用:
request.setAttribute(objectname,Objectvalue);
request.getAttribute(Objectobj);
- **作用:**解决了一次请求内的不同 Servlet 的数据(请求数据+其他数据)共享问题。
- **作用域:**基于请求转发,一次请求中的所有 Servlet 共享。
- **注意:**使用 Request 对象进行数据流转,数据只在一次请求内有效。
- **特点:**1.服务器创建 2.每次请求都会创建 3.生命周期一次请求
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
//获取作用域对象
req.getAttribute("str")
//login.java登录处理页面
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
resp.getWriter().write("登录成功");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
//page.java 登录页面
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PageServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
// 处理请求
// 响应处理结果
//获取作用域对象
String str = (String) req.getAttribute("str")==null?"":(String) req.getAttribute("str");
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<font color='red' size='20px'>"+str+"</font>");
resp.getWriter().write("<form action='login' method='post'>");
resp.getWriter().write("用户名:<input type='text' name='uname' value=''/><br/>");
resp.getWriter().write("密码:<input type='password' name='pwd' value=''/><br/>");
resp.getWriter().write("<input type='submit' value='登录'/><br/>");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
登录页面
输入错误的用户名密码转发后的页面
3.6servlet学习-重定向学习
-
**重定向:**解决了表单重复提交的问题,以及当前servlet无法处理的请求的问题。
-
使用:
resp.sendRedirect(String uri);
-
示例:
resp.sendRedirect("/login/main");
-
特点: 1.两次请求,两个request对象。2.浏览器地址栏信息改变
-
时机:
1.如果请求中有表单数据,而数据又比较重要,不能重复提交,建议使用重定向。
2.如果请求被Servlet接收后,无法进行处理,建议使用重定向定位到可以处理的源。
//main登录成功后的页面
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MainServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+req.getParameter("uname")+"访问JAVA管理系统</h3>");
resp.getWriter().write("<hr>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
//login登录验证页面
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
//重定向
resp.sendRedirect("/test/main");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
好处:防止了表单的重复提交
存在问题:因为存在两次请求,所以无法流转第一个servlet的数据
四、servlet学习-Cookie
4.1cookie的创建
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//响应cookie信息
resp.addCookie(c);
package cookie.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//响应cookie信息
resp.addCookie(c);
//直接响应
resp.getWriter().write("cookie学习");
}
}
特点:cookie会存储在浏览器的运行内存中,请求同项目其他地址会附带。
问题:关闭浏览器cookie会失效
解决:设置有效期
4.2cookie的有效期
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//设置cookie有效期(单位秒)
c.setMaxAge(3600*24*3);
//响应cookie信息
resp.addCookie(c);
package cookie.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//设置cookie有效期(单位秒)
c.setMaxAge(3600*24*3);
//响应cookie信息
resp.addCookie(c);
//直接响应
resp.getWriter().write("cookie学习");
}
}
特点:cookie存储在硬盘中,在设置时间(3天)内不会失效
**问题:**同项目下每个请求都附带cookie
解决:设置cookie有效路径
4.3设置cookie有效路径
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//设置cookie有效期(单位秒)
c.setMaxAge(3600*24*3);
//设置有效路径
c2.setPath("/cookie/abc");
//响应cookie信息
resp.addCookie(c);
package cookie.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//创建cookie对象
Cookie c = new Cookie("phone", "MI");
//设置cookie有效期(单位秒)
c.setMaxAge(3600*24*3);
//设置cookie有效路径
c.setPath("/cookie/abc");
//响应cookie信息
resp.addCookie(c);
//直接响应
resp.getWriter().write("cookie学习");
}
}
作用:在访问/cookie/abc才会附带cookie信息,其他地址则不会附带
4.4Cookie信息的获取
//获取cookie信息
Cookie[] cks = req.getCookies();
if(cks!=null) {
for(Cookie c:cks) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
}
//存储cookie ck
package cookie.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//创建cookie对象
Cookie c1 = new Cookie("phone", "MI");
Cookie c2 = new Cookie("laptop", "HUAWEI");
//设置cookie有效期(单位秒)
c1.setMaxAge(3600*24*3);
c2.setMaxAge(3600*24*3);
//设置cookie有效路径
c1.setPath("/cookie/gc");
c2.setPath("/cookie/gc");
//响应cookie信息
resp.addCookie(c1);
resp.addCookie(c2);
//直接响应
resp.getWriter().write("cookie学习");
}
}
//读取cookie gc
package cookie.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetCookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取cookie信息
Cookie[] cks = req.getCookies();
if(cks!=null) {
for(Cookie c:cks) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
}
}
}
控制台
phone:MI
laptop:HUAWEI
4.5Cookie使用之三天免登陆
1.返回登录页面
//ck
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
Cookie[] cks = req.getCookies();
//处理请求信息
if(cks!=null) {
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
}
}
}
2.存储cookie信息
//创建Cookie信息实现三天免登录
Cookie c = new Cookie("uid", u.getUid()+"");
//设置cookie有效期
c.setMaxAge(3*24*3600);
//设置有效路径
c.setPath("/test/ck");
//添加cookie信息
resp.addCookie(c);
//login登录验证
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
//创建Cookie信息实现三天免登录
Cookie c = new Cookie("uid", u.getUid()+"");
//设置cookie有效期
c.setMaxAge(3*24*3600);
//设置有效路径
c.setPath("/test/ck");
//添加cookie信息
resp.addCookie(c);
//重定向
resp.sendRedirect("/test/main");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
//ck免登录验证
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
Cookie[] cks = req.getCookies();
//处理请求信息
if(cks!=null) {
resp.sendRedirect("/test/main");
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
}
}
}
浏览器:
http://localhost:8000/test/ck
跳转到:
http://localhost:8000/test/main
存在问题:如果用户注销,而三天免登录cookie还在,用户还可以访问主页
解决:查数据库检查
3.查数据库验证
if(cks!=null) {
//遍历cookie信息
String uid="";
for(Cookie c:cks) {
//遍历cookie名为uid的key
if("uid".equals(c.getName())) {
//获取key为uid的值
uid=c.getValue();
}
//检验uid是否存在
if("".equals(uid)) {
req.getRequestDispatcher("page").forward(req, resp);
return;
}else {
//校验UID用户信息
//获取业务层对象--查库
LoginService ls = new LoginServiceImpl();
User u = ls.checkUidService(uid);
if(u!=null) {
//重定向
resp.sendRedirect("/test/main");
return;
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
}
//uid校验
package com.zh.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zh.model.User;
import com.zh.service.LoginService;
import com.zh.service.impl.LoginServiceImpl;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
Cookie[] cks = req.getCookies();
//处理请求信息
if(cks!=null) {
//遍历cookie信息
String uid="";
for(Cookie c:cks) {
//遍历cookie名为uid的key
if("uid".equals(c.getName())) {
//获取key为uid的值
uid=c.getValue();
}
//检验uid是否存在
if("".equals(uid)) {
req.getRequestDispatcher("page").forward(req, resp);
return;
}else {
//校验UID用户信息
//获取业务层对象--查库
LoginService ls = new LoginServiceImpl();
User u = ls.checkUidService(uid);
if(u!=null) {
//重定向
resp.sendRedirect("/test/main");
return;
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
//service接口
package com.zh.service;
import com.zh.model.User;
public interface LoginService {
//校验用户登录信息
public User CheckLoginService(String uname,String pwd);
//校验用户uid
public User checkUidService(String uid);
}
//service实例
package com.zh.service.impl;
import com.zh.dao.LoginDao;
import com.zh.dao.impl.LoginDaoImpl;
import com.zh.model.User;
import com.zh.service.LoginService;
public class LoginServiceImpl implements LoginService{
//创建Dao层对象
LoginDao ld = new LoginDaoImpl();
//校验用户登录信息
@Override
public User CheckLoginService(String uname, String pwd) {
return ld.checkLoginDao(uname, pwd);
}
//校验用户uid
@Override
public User checkUidService(String uid) {
return ld.checkUidDao(uid);
}
}
//dao层接口
package com.zh.dao;
import com.zh.model.User;
public interface LoginDao {
//根据用户名和密码获取用户信息
public User checkLoginDao(String uname,String pwd);
//根据uid获取用户信息
public User checkUidDao(String uid);
}
//dao层实现
package com.zh.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.zh.dao.LoginDao;
import com.zh.model.User;
public class LoginDaoImpl implements LoginDao {
// 根据用户名和密码获取用户信息
@Override
public User checkLoginDao(String uname, String pwd) {
// 声明Jdbc对象
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
// 声明数据存储对象
User u = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
// 创建Sql命令
String sql = "select * from t_user where uname=? and pwd=?";
// 创建Sql命令对象
ps = conn.prepareStatement(sql);
// 给占位符赋值
ps.setString(1, uname);
ps.setString(2, pwd);
// 执行
rs = ps.executeQuery();
// 遍历执行结果
while (rs.next()) {
u = new User();
u.setUid(rs.getInt("uid"));
u.setUname(rs.getString("uname"));
u.setPwd(rs.getString("pwd"));
}
// 关闭资源
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return u;
}
// 根据uid获取用户信息
@Override
public User checkUidDao(String uid) {
// 声明Jdbc对象
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
// 声明数据存储对象
User u = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
// 创建Sql命令
String sql = "select * from t_user where uid=?";
// 创建Sql命令对象
ps = conn.prepareStatement(sql);
// 给占位符赋值
ps.setString(1, uid);
// 执行
rs = ps.executeQuery();
// 遍历执行结果
while (rs.next()) {
u = new User();
u.setUid(rs.getInt("uid"));
u.setUname(rs.getString("uname"));
u.setPwd(rs.getString("pwd"));
}
// 关闭资源
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return u;
}
}
五、session学习
**问题:**一个用户的不同请求处理的数据共享怎么办?
**解决:**使用session技术
**原理:**用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够获取到共享的数据。
特点:1.存储在服务器端 2.服务器进行创建 3.依赖Cookie技术 4.一次会话 5.默认存储时间是30分钟
**作用:**解决了一个用户不同请求处理的数据共享问题
**简单理解:**用户第一次访问服务器,服务器将在服务器上创建一个柜子(session对象),并将打开柜子的钥匙(JSESSIONID)发送到浏览器存储(使用cookie技术),用户访问其他页面时就会附带这个钥匙(JSESSIONID)
总结:
session解决了一个用户的不同请求的数据共享问题,只要在JSESSIONID不失效和session对象不失效的情况下。
用户的任意请求在处理时都能获取到同一个session对象。
**作用域:**1.一次会话 2.在JSESSIONID和SESSION对象不失效的情况下为整个项目内。
**session失效处理:**将用户请求中的JSESSIONID和后台获取到的SESSION对象的JSESSIONID进行比对,如果一致
则session没有失效,如果不一致则证明session失效了。重定向到登录页面,让用户重新登录。
注意:JSESSIONID存储在了Cookie的临时存储空间中,浏览器关闭即失效。
5.1创建和获取session对象
//创建session对象
/*
1.如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
2.如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JSESSIONID作为从cookie数据存储到浏览器内存中
3.如果session对象是失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中。
*/
HttpSession hs = req.getSession();
public class SessionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset;utf-8");
//创建session对象
HttpSession hs = req.getSession();
}
}
浏览器存储JSESSIONID,在访问同项目其他路径就会携带
失效3种情况
1.cookie被清除
2.关掉了浏览器
3.服务端的session超时被销毁
//获取session对象
HttpSession hs = req.getSession();
System.out.println("获取JJSESSIONID:"+hs.getId());
public class SessionServlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession hs = req.getSession();
System.out.println("获取JJSESSIONID:"+hs.getId());
}
}
浏览器:
http://localhost:8000/session/ss2
控制台:
获取JJSESSIONID:F600094776C95430C610E678AA4AA0C1
5.2设置session存储时间
//创建session对象
HttpSession hs = req.getSession();
//设置session存储时间(单位秒)
hs.setMaxInactiveInterval(5);
public class SessionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset;utf-8");
//创建session对象
HttpSession hs = req.getSession();
//设置session存储时间(单位秒)
hs.setMaxInactiveInterval(5);
}
}
超时访问生成新的JSESSIONID
在指定的时间内session对象没有被使用则销毁,如果使用了则重新计时。
如果在5秒内又访问则又重新计时5秒,session对象不会销毁
5.3设置session强制失效
作用:当用户退出登录时主动销毁session
//设置强制失效
hs.invalidate();
public class SessionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset;utf-8");
//创建session对象
HttpSession hs = req.getSession();
//设置session存储时间(单位秒)
hs.setMaxInactiveInterval(5);
//设置强制失效
hs.invalidate();
}
}
5.4session存储和获取数据
//存储数据
String name = "张三";
hs.setAttribute("name", name);
public class SessionServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset;utf-8");
//创建session对象
HttpSession hs = req.getSession();
//存储数据
String name = "张三";
hs.setAttribute("name", name);
}
}
//取数据
hs.getAttribute("name")
public class SessionServlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession hs = req.getSession();
System.out.println("获取JJSESSIONID:"+hs.getId());
System.out.println("name:"+hs.getAttribute("name"));
}
}
存数据
取数据
浏览器:
http://localhost:8000/session/ss2
控制台
获取JJSESSIONID:9B9D3A88910624E8FE79E93F0E0883AB
name:张三
存储和获取数据
存储:hs.setAttribute(String name,Object value);
获取:hs.getAttribute(String name)
返回的数据类型为Object
注意:存储的动作和取出的动作发生在不同的请求中,但是存储要先于取出执行。
**使用时机:**一般用户在登陆web项目时会将用户的个人信息存储到Sesion中,供该用户的其他请求使用。
5.5修改session默认失效时间
<!--D:\tomcat\conf\web.xml-->
<!--注意:
1.全局模式:修改tomcat下的web.xml,tomcat下所有项目有效
2.局部模式:在项目下的web.xml添加如下代码
-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5.6session登录练习使用解决null显示问题
思路:
1.在登录验证servlet中存入session对象,在主页取出session对象
2.存在问题:因为三天免登录,在退出浏览器session对象销毁,主页将不能取出数据造成空指针异常
3.在cookie验证页面验证后,存储session
4.在主页添加查看个人信息按钮
1.存取数据
//将数据存储到session对象中
HttpSession hs = req.getSession();
hs.setAttribute("user", u);
//取数据
HttpSession hs = req.getSession();
User u = (User) hs.getAttribute("user");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问JAVA管理系统</h3>");
//存数据
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
//创建Cookie信息实现三天免登录
Cookie c = new Cookie("uid", u.getUid()+"");
//设置cookie有效期
c.setMaxAge(3*24*3600);
//设置有效路径
c.setPath("/test/ck");
//添加cookie信息
resp.addCookie(c);
//将数据存储到session对象中
HttpSession hs = req.getSession();
hs.setAttribute("user", u);
//重定向
resp.sendRedirect("/test/main");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
public class MainServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
HttpSession hs = req.getSession();
User u = (User) hs.getAttribute("user");
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问JAVA管理系统</h3>");
resp.getWriter().write("<hr>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
存在问题:在退出浏览器session对象销毁,主页将不能取出数据造成空指针异常
解决:在cookie免登录验证页存入session
2.存取数据
/ck
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
//创建Cookie信息实现三天免登录
Cookie c = new Cookie("uid", u.getUid()+"");
//设置cookie有效期
c.setMaxAge(3*24*3600);
//设置有效路径
c.setPath("/test/ck");
//添加cookie信息
resp.addCookie(c);
//将数据存储到session对象中
HttpSession hs = req.getSession();
hs.setAttribute("user", u);
//重定向
resp.sendRedirect("/test/main");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
3.添加查看个人信息
resp.getWriter().write("<form action='show' method='get'>");
resp.getWriter().write("<input type='submit' value='查看个人信息'>");
resp.getWriter().write("</form>");
//main
public class MainServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
HttpSession hs = req.getSession();
User u = (User) hs.getAttribute("user");
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问JAVA管理系统</h3>");
resp.getWriter().write("<hr>");
resp.getWriter().write("<form action='show' method='get'>");
resp.getWriter().write("<input type='submit' value='查看个人信息'>");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
//show
public class ShowServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求编码格式
req.setCharacterEncoding("utf-8");
// 设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
// 获取请求信息
HttpSession hs = req.getSession();
if (hs.getAttribute("user") == null) {
// 重定向
resp.sendRedirect("/login/ck");
return;
}
User u = (User) hs.getAttribute("user");
// 处理请求信息
// 响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<table border='1px'>");
resp.getWriter().write("<tr>");
resp.getWriter().write("<td>用户名</td>");
resp.getWriter().write("<td>" + u.getUname() + "</td>");
resp.getWriter().write("</tr>");
resp.getWriter().write("<tr>");
resp.getWriter().write("<td>密码</td>");
resp.getWriter().write("<td>" + u.getPwd() + "</td>");
resp.getWriter().write("</tr>");
resp.getWriter().write("</table>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
六、ServletContext对象学习
ServletContext对象学习:
**问题:**不同的用户使用相同的数据
**解决:**ServletContext对象
特点: 1.服务器创建 2.用户共享
**作用域:**整个项目内
**生命周期:**服务器启动到服务器关闭
6.1获取ServletContext对象三种方法
//获取servletContext的三种方式:
//第一种方式(常用)
ServletContext sc1 = this.getServletContext();
//第二种方式
ServletContext sc2 = this.getServletConfig().getServletContext();
//第三种方式(常用)
ServletContext sc3 = req.getSession().getServletContext();
public class ServletContextServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取servletContext的三种方式:
//第一种方式
ServletContext sc1 = this.getServletContext();
//第二种方式
ServletContext sc2 = this.getServletConfig().getServletContext();
//第三种方式
ServletContext sc3 = req.getSession().getServletContext();
System.out.println(sc1==sc2);
System.out.println(sc1==sc3);
}
}
浏览器:
http://localhost:8000/ServletContext/context
控制台:
true
true
结论:通过三种方式拿到的是同一个对象
6.2使用ServletContext对象的存取
数据存储 sc.setAttribute(String name, Object value);
数据获取sc.getAttribute("str") 返回的是Object类型
注意:不同的用户可以给ServletContext对象进行数据的存取。获取的数据不存在返回null。
//数据存储
sc.setAttribute("str", "servletcontext学习");
//获取数据
sc.getAttribute("str");
//数据存储
public class ServletContextServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取servletContext的三种方式:
//第一种方式
ServletContext sc1 = this.getServletContext();
//使用ServletContext对象完成数据共享
//数据存储
sc1.setAttribute("str", "servletcontext学习");
}
}
//数据获取
public class ServletContextServlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建servletcontext对象
ServletContext sc = this.getServletContext();
//获取数据
System.out.println(sc.getAttribute("str"));
}
}
浏览器:
先 http://localhost:8000/ServletContext/context
后 http://localhost:8000/ServletContext/context2
控制台
servletcontext学习
6.3获取项目中web.xml文件中的全局配置数据
获取项目中web.xml文件中的全局配置数据
sc.getInitParameter(String name);
根据键的名字返回web.xml中配置的全局数据的值,返回String类型。
如果数据不存在返回null。
sc.getInitParameterNames();
返回键名的枚举
**配置方式:**注意 一组标签只能存储一组键值对数据,多组可以声明多个 进行存储。
作用: 将静态数据(不可改变)和代码进行解耦。对于一些重要数据的修改避免改源码。
<!-- 配置全局数据 -->
<context-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</context-param>
<!-- 配置多个全局参数 -->
<context-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</context-param>
<context-param>
<param-name>age</param-name>
<param-value>18</param-value>
</context-param>
//获取项目web.xml的全局配置数据
String name = sc.getInitParameter("name");
System.out.println(name);
public class ServletContextServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取servletContext的三种方式:
//第一种方式
ServletContext sc = this.getServletContext();
//使用ServletContext对象完成数据共享
//数据存储
sc.setAttribute("str", "servletcontext学习");
//获取项目web.xml的全局配置数据
String name = sc.getInitParameter("name");
System.out.println("全局参数:"+name);
}
}
控制台:
全局参数:zhangsan
6.4获取项目webroot下的资源的绝对路径和流对象。
1.获取项目webroot下的资源的绝对路径,eclipse下为WebContent
//获取项目根目录下的资源的绝对路径
1.String path = "D:\\apache-tomcat-7.0.56\\webapps\\sc\\doc\\1.txt";
System.out.println(path);
//存在问题,当项目部署到远程服务器或没有D盘将出错
//获取项目根目录下的资源的绝对路径
2.String path = sc.getRealPath("/doc/1.txt");
System.out.println(path);
2.获取webroot下的资源的流对象
//获取项目根目录下资源的流对象
InputStream is = sc.getResourceAsStream("/doc/1.txt");
注意:此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取。
6.5使用ServletContext对象完成网页计数器
-
在用户登录校验中创建计数器并自增,然后存储到ServletContext对象中
-
在主页面里取出计数器数据显示给用户即可。
//创建网络计数器
//获取计数器数据
ServletContext sc = this.getServletContext();
int nums = (int) sc.getAttribute("nums");
//计数器自增
nums+=1;
//再次存储到ServletContext对象中
sc.setAttribute("nums", nums);
问题:在第一次访问的时候ServletContext中还没有nums,直接取将会报空指针异常
解决:访问时先判断nums是否为空,如果为空就给nums存一个1
//获取计数器数据
ServletContext sc = this.getServletContext();
if(sc.getAttribute("nums")!=null) {
int nums = (int) sc.getAttribute("nums");
//计数器自增
nums+=1;
//再次存储到ServletContext对象中
sc.setAttribute("nums", nums);
}else {
sc.setAttribute("nums", 1);
}
//获取人数
ServletContext sc = this.getServletContext();
int nums = (int) sc.getAttribute("nums");
//简写
int nums = (int)this.getServletContext().getAttribute("nums");
resp.getWriter().write("当前访问人数:"+nums);
//获取计数器存数据
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls = new LoginServiceImpl();
//响应处理结果
User u=ls.CheckLoginService(uname, pwd);
if(u!=null) {
//创建Cookie信息实现三天免登录
Cookie c = new Cookie("uid", u.getUid()+"");
//设置cookie有效期
c.setMaxAge(3*24*3600);
//设置有效路径
c.setPath("/test/ck");
//添加cookie信息
resp.addCookie(c);
//将数据存储到session对象中
HttpSession hs = req.getSession();
hs.setAttribute("user", u);
//创建网络计数器
//获取计数器数据
ServletContext sc = this.getServletContext();
if(sc.getAttribute("nums")!=null) {
int nums = (int) sc.getAttribute("nums");
//计数器自增
nums+=1;
//再次存储到ServletContext对象中
sc.setAttribute("nums", nums);
}else {
sc.setAttribute("nums", 1);
}
//重定向
resp.sendRedirect("/test/main");
}else {
//存取request作用域对象
req.setAttribute("str", "用户名或密码错误");
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
//获取人数
public class MainServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//获取请求信息
int nums = (int)this.getServletContext().getAttribute("nums");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
HttpSession hs = req.getSession();
User u = (User) hs.getAttribute("user");
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问JAVA管理系统</h3>");
resp.getWriter().write("当前访问人数:"+nums);
resp.getWriter().write("<hr>");
resp.getWriter().write("<form action='show' method='get'>");
resp.getWriter().write("<input type='submit' value='查看个人信息'>");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
第一次访问
http://localhost:8000/test/ck
输入密码登录
第二访问
http://localhost:8000/test/page
输入密码登录
再次访问ck
http://localhost:8000/test/ck
问题:应为cookie校验通过–>没有走login验证–>没有进行nums加1
解决:在cookie验证通过中也加入+1操作
//cookie验证 ck
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
Cookie[] cks = req.getCookies();
//处理请求信息
if(cks!=null) {
//遍历cookie信息
String uid="";
for(Cookie c:cks) {
//遍历cookie名为uid的key
if("uid".equals(c.getName())) {
//获取key为uid的值
uid=c.getValue();
}
//检验uid是否存在
if("".equals(uid)) {
req.getRequestDispatcher("page").forward(req, resp);
return;
}else {
//校验UID用户信息
//获取业务层对象--查库
LoginService ls = new LoginServiceImpl();
User u = ls.checkUidService(uid);
if(u!=null) {
//获取计数器数据
int nums = (int) this.getServletContext().getAttribute("nums");
nums+=1;
//存入数据
this.getServletContext().setAttribute("nums", nums);
//重定向
HttpSession hs = req.getSession();
hs.setAttribute("user", u);
resp.sendRedirect("/test/main");
return;
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
}else {
//响应处理结果
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
第一次访问
http://localhost:8000/test/ck
输入密码登录
第二次访问
http://localhost:8000/test/ck
第三次访问
http://localhost:8000/test/ck
问题:当服务器重启或关闭的时候数据就失效
解决:新建一个servlet加入初始化方法和销毁方法,当服务器开启时读入数据,销毁时存入到文件中
//销毁方法--关闭服务器将数据存入nums.txt
public void destroy() {
//获取计数器
ServletContext sc = this.getServletContext();
int nums = (int)sc.getAttribute("nums");
//获取文件路径
String path = sc.getRealPath("/nums/nums.txt");
//声明流对象
BufferedWriter bw = null;
FileWriter fw = null;
try {
fw=new FileWriter(path);
bw=new BufferedWriter(fw);
bw.write(nums+"");
bw.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//初始化方法---将从nums中读入数据
public void init() throws ServletException {
//获取文件中的计数器数据
//获取文件路径
String path=this.getServletContext().getRealPath("/nums/nums.txt");
//声明流对象
FileReader fr=null;
BufferedReader br=null;
try {
fr=new FileReader(path);
br=new BufferedReader(fr);
int nums=Integer.parseInt(br.readLine());
System.out.println(nums);
this.getServletContext().setAttribute("nums", nums);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
<!--<load-on-startup>1</load-on-startup>初始化加载-->
<servlet>
<description></description>
<display-name>NumServlet</display-name>
<servlet-name>NumServlet</servlet-name>
<servlet-class>com.zh.servlet.NumServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
七、servlet学习-servletConfig对象
- ServletConfig对象学习:
- 问题:如何获取在web.xml中给每个servlet单独配置的数据呢?
- **解决:**使用ServletConfig对象
- **使用:**获取ServletConfig对象获取web.xml中的配置数据
<!--web.xml配置
注意:需要配置到servlet里面
-->
<servlet>
<description></description>
<display-name>ServletConfigServlet</display-name>
<servlet-name>ServletConfigServlet</servlet-name>
<servlet-class>com.zh.servlet.ServletConfigServlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>config</param-value>
</init-param>
</servlet>
//获取ServletConfig对象
ServletConfig sc = this.getServletConfig();
//获取web.xml中配置的数据
String name = sc.getInitParameter("name");
public class ServletConfigServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletConfig对象
ServletConfig sc = this.getServletConfig();
//获取web.xml中配置的数据
String name = sc.getInitParameter("name");
System.out.println(name);
}
}
浏览器:
http://localhost:8000/ServletConfig/config
控制台:
config
上一篇: Mysqldump_MySQL
下一篇: 有关PHP文档生成工具