知识整理

#Servlet
1.概念
2.步骤
3.执行原理
4.生命周期
5.Servlet3.0注解配置
6.Servlet的体系结构
* Servlet----接口

	* GenericServlet--抽象类	
		
	* HttpServlet--抽象类
	
	* GenericServlet将Servlet接口中其他的方法做了默认空实现,只将service()方法
	* 作为抽象,将来定义Servlet类时,可以继承GenericServlet,实现service()方法杰克
	
	* HttpServlet:对http协议的一种封装,简化操作
		1.定义类继承HttpServlet
		2.复写doGet/doPost方法

#Servlet相关配置
1.urlpattern:Servlet访问路径
* 一个Servlet可以定义多个访问路径:@WebServlet({"/D4",“DD4”})
* 路径的定义规则:
* 1./xxx
* 2./xxx/xxx多层路径,目录结构
* 3.*.do
#HTTP协议
* 概念:Hyper Text Transfer Protocol 超文本传输协议
* 传输协议: 定义了,客户端和服务器端通信时,发送数据的格式
* 特点:
* 基于TCP/IP的高级协议
* 默认端口号:80
* 基于请求/响应模型的:一次请求对应一次响应
* 无状态的:每次请求之间相互独立,不能交互数据
* 历史版本
* 1.0每次请求都建立一次连接
* 1.0复用连接
* 请求消息数据格式
* 请求行
* 请求方式 请求url 请求的协议/版本
* GET /请求内容 HTTP/1.1
* 请求方式
* HTTP协议有7中请求方式,常用的有2中
* GET
* 请求参数在url中
* 请求的url长度是有限制的
* 不安全
* POST
* 请求参数在请求体中
* 请求url长度没有限制
* 相对安全
* 请求头
* 请求头名称:请求头值
* 常见的请求头
* 1.User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
* 可以在服务器端获取头的信息,解决浏览器的兼容性问题
* Referer:
* 告诉服务器当前请求从哪里来?
* 作用:
* 1.防盗链:
* 2.统计:
* Connection:可以被复用
* 请求空行
* 做分隔作用
* 请求体
* 封装POST请求消息的请求参数的
* 响应消息数据方式

	* tomcat服务器会根据请求url中的资源路径,创建对应的ServletDemo1的对象
	* tomcat服务器,会创建request和response对象,request对象中封装请求消息数据
	* tomcat将request和response两个对象传递给service方法,并且调用service方法
	* 通过request对象获取请求消息数据,通过response对象设置响应消息数据
	* 服务器在给浏览器做出响应之前,会从response对象中拿程序员设置的响应消息数据

1.request对象和response对象的原理
	* request和response对象是由服务器创建的
	* request对象是来获取请求消息,response对象是来响应消息
2.request对象继承体系结构
servletRequest    -----接口   
		|	继承
HttpservletRequest	----	接口
		|	实现
org.apache.catalina.connector.RequestFacade 类(tomcat)

3.request功能:
	1. 获取请求消息数据
		1. 获取请求行数据
			* GET/DAY/DEMO!?name=张山 Http/1.1
			* 方法:
				* 获取请求方式:GET
					* string getMethod()
				* 获取虚拟目录:/DAY
					* String getContextPath()
				* 获取Servlet路径:/DEMO
					* String getServletPath()
				* 获取get方式请求参数:
					* String getQueryString()
				* 获取请求URI
					* String getRequestURI()
					* StringBuffer getRequsetURL()
				* 获取协议及版本:Http/1.1
					* String getProtocol()
				* 获取客户机的IP地址
					* String getRemoteAddr()
		2. 获取请求头数据
			* 方法:
				* String getHeader(String name):通过请求头的名称获取请求头的值
				* Enumeration<String> getHeadernames():获取所有的请求头名称
		3. 获取请求体数据
			1. 只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
			2. 步骤:
				1. 获取流对象
					1. BufferedReader getReader():获取字符输入流,只能操作字符数据
					2. ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
				2. 再从流对象中拿数据
				
	2. 其他功能
		1. 获取请求参数通用方式
			1. String getParameter(String name):根据参数名称获取参数值 
			2. String getParameterValues(String name):根据参数名称获取参数值的数组 
			3. Enumeration<String> getParameterNames():获取所有请求参数名称
			4. Map<String,String[]> getParameterMap():获取所有参数的map集合
			中文乱码问题				
				* get方式:tomcat已经将get方式乱码问题解决了
				* post方式:会乱码
					* 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8")
					
		2. 请求转发:一种在服务器内部的资源跳转方式
			1. 步骤:
				1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
				2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
			2. 特点
				1. 浏览器地址栏路径不发生变化
				2. 只能转发到当前服务器内部的资源中
				3. 转发是一次请求
					
		3. 共享数据:
			1. 域对象:一个有作用范围的对象,可以在范围内共享数据
			2. request域:代表一次请求的范围,一般用于请求转发的多个资源共享数据
			3. 方法:
				1. setAttribute(String name,Object obj):存储数据
				2. Object getAttitude(String name):通过键获取值
				3. removeAttribute(String name)通过键移除键值对
		4. 获取ServietContext:
			1. ServletContext getServletContext();

##案例:用户登陆
* 用户登陆案例需求
* 编写login.html登陆页面
* username&password两个输入框
* 使用Druid数据库连接池技术,操作MySQL,day14数据库中user表
* 使用jdbcTemplate技术封装JDBC
* 登陆成功跳转到SuccessServlet展示:登陆成功!用户名,欢迎您
* 登陆失败跳转到FailServlet展示:登陆失败,用户名或密码错误
开发步骤
1. 创建项目,导入HTML页面,配置文件,jar包
2. 创建数据库对象
3. 创建一个包,创建user类
/**
* 用户的实体类
*/
public class User {
private int id;
private String username;
private String password;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

@Override
public String toString() {
    return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", password='" + password + '\'' +
            '}';
}
}

#4.创建一个包,创建类UserDao,提供login方法

	/**
* 操作数据库中User表的类
*/
public class UserDao {

//声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

/**
 * 登录方法
 * @param loginUser 只有用户名和密码
 * @return user包含用户全部数据,没有查询到,返回null
 */
public User login(User loginUser){
    try {
        //1.编写sql
        String sql = "select * from user where username = ? and password = ?";
        //2.调用query方法
        User user = template.queryForObject(sql,
                new BeanPropertyRowMapper<User>(User.class),
                loginUser.getUsername(), loginUser.getPassword());


        return user;
    } catch (DataAccessException e) {
        e.printStackTrace();//记录日志
        return null;
    }
}
}

/**
 * 用户的实体类
*/
public class User {

private int id;
private String username;
private String password;

private String gender;

public void setHehe(String gender){
    this.gender = gender;
}

public String getHehe(){
    return gender;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

@Override
public String toString() {
    return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", password='" + password + '\'' +
            ", gender='" + gender + '\'' +
            '}';
}
}


**
 * JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {

private static DataSource ds ;

static {

    try {
        //1.加载配置文件
        Properties pro = new Properties();
        //使用ClassLoader加载配置文件,获取字节输入流
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);

        //2.初始化连接池对象
        ds = DruidDataSourceFactory.createDataSource(pro);

    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * 获取连接池对象
 */
public static DataSource getDataSource(){
    return ds;
}


/**
 * 获取连接Connection对象
 */
public static Connection getConnection() throws SQLException {
    return  ds.getConnection();
}
}

#登陆的具体逻辑
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.设置编码
    req.setCharacterEncoding("utf-8");
   /* //2.获取请求参数
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    //3.封装user对象
    User loginUser = new User();
    loginUser.setUsername(username);
    loginUser.setPassword(password);*/
    //2.获取所有请求参数
    Map<String, String[]> map = req.getParameterMap();
    //3.创建User对象
    User loginUser = new User();
    //3.2使用BeanUtils封装
    try {
        BeanUtils.populate(loginUser,map);
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }


    //4.调用UserDao的login方法
    UserDao dao = new UserDao();
    User user = dao.login(loginUser);

    //5.判断user
    if(user == null){
        //登录失败
        req.getRequestDispatcher("/failServlet").forward(req,resp);
    }else{
        //登录成功
        //存储数据
        req.setAttribute("user",user);
        //转发
        req.getRequestDispatcher("/successServlet").forward(req,resp);
    }

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    this.doGet(req,resp);
}
}

##1.Http协议:响应消息
1.请求消息:客户端发送给服务器的数据
* 数据格式
* 请求行
* 请求头
* 请求空行
* 请求体
* Host: home.firefoxchina.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;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, br
Connection: keep-alive
Cookie: acw_tc=7b39758815729304218548467ec17463db1c21c6a47979ae4af6194eb808fb; Hm_lvt_dd4738b5fb302cb062ef19107df5d2e4=1572930423; Hm_lpvt_dd4738b5fb302cb062ef19107df5d2e4=1572930423
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
2.响应消息:服务器端发送给客户端的数据
* 数据格式
* 响应行
* 组成:协议/版本 响应的状态码 状态码的描述
* 响应的状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
1. 状态码都是3位数字
2. 分类
1. 1xx:服务器接收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
2. 2xx:成功,代表:200
3. 3xx:重定向。代表:302(重定向)304访问缓存
4. 4xx:客户端错误 代表:404(请求路径没有对应的资源)405:请求方式没有对应的doxxx()方法
5. 5xx:服务器错误
* 代表500:服务器内部出现异常
* attachment;filename=xxx:以附件形式打开响应体。文件下载
* 响应头
* 格式:头名称:值
* 常见的响应头
* Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
* Content-disposition:服务器告诉客户端以什么格式打开响应体数据
* 值:
* in-line:默认值,在当前页面内打开
* 响应空行
* 响应体
* 发送传输的数据,传输的真实数据
HTTP/1.1 200
Set-Cookie: JSESSIONID=F2F555BE8B43C5EBD2B579236128F855; Path=/day15; HttpOnly
Content-Type: text/html;charset=UTF-8
Content-Length: 96
Date: Tue, 05 Nov 2019 05:17:47 GMT(Cdn Cache Server V2.0)

##2.Response对象
* 功能:设置响应消息
* 设置响应行
* 格式:HTTP/1.1-200 ok
* 设置状态码:setstatus(int sc)
* 设置响应头
* setHeader(string name,String value)
* 设置响应体
* 使用步骤
* 获取输出流
* 字符输出流
* PrintWriter getWriter()

				* 字节输出流:ServletOutputStream getOutputStream()
			* 使用输出流,将数据输出到客户端浏览器

##3.ServletContent对象
1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信
2. 功能:
1. 获取MIME类型:
1. 在互联网通信的过程中定义的一种文件数据类型
1. 格式:大类型/小类型 text/html image/jpeg
* 获取String getMineType(String file)
2. 域对象:共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
ServletContent对象范围,所有用户所有请求的数据
3. 获取文件的真实(服务器)路径
1. 方法:String getRealPath(String path)

3. 获取:
	1. 可以通过request.getServletContent
	2. 通过httpServlet获取
		1. getServletContent()
		
	



* 案例:
	* 完成重定向:简单的重定向 response.sendRedirect();
		* 重定向的特点
			* 地址栏发生变化
			* 重定向可以访问其他站点(服务器)的资源
			* 重定向是两次请求,不可以使用request对象来共享数据
		* 转发向的特点
			* 转发地址栏不变
			* 转发只能访问当前服务器下的资源
			* 转发是一次请求,可以使用request对象来共享数据
		* 路径写法:
			* 路径的分类
				* 相对路径:通过相对路径不可以确定唯一资源
					* 如:./index.html
					* 不以/开头,以.开头路径
					* 规则:确定访问当前资源和目标资源之间的相对位置关系
				* 绝对路径:通过绝对路径可以确定唯一资源
					* 如:http://localhost/day15/sda
					* 以/开头的路径
					* 规则:判断定义的路径是谁用的
						* 给客户端浏览器使用:需要加虚拟路径(项目的访问路径)
							* 建议虚拟目录动态获取
						* 给服务器使用:不需要加虚拟目录
					动态获取虚拟目录request.getContentPath();
			
	* 服务器输出字符数据到浏览器
		* 步骤:
			* 获取字符输出流
			* 输出数据
				* 乱码问题:编码使用的字符集不一致
					* setcontentType();
					* 设置该流的编码
					* 告诉浏览器响应体使用的编码
	* 服务器输出字节数据到浏览器
		*获取字符输出流
		* 输出数据
	* 验证码

##文件下载按钮
文件下载需求
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载

分析:
* 超链接指向的资源如果能过被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框,不能满足需求
* 任何资源都必须弹出下载提示框
* 使用响应头设置资源的打开方式
	* content-disposition:attachment;filename=xxx

* 步骤:
	* 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
	* 定义Servlet
		* 获取文件名称
		* 使用字节输入流加载文件进内存
		* 指定response的响应头:content-disposition:attachment;filename=xxx
		* 将数据写出到response输出流

#会话技术
会话:一次会话中包含多次请求和响应。
* 一次会话指的是浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
* 功能:在一次会话的范围内的多次请求间,共享数据
* 方式:
* 客户端会话技术:Cookie
* 服务器端会话技术Session
#Cookie
1. 概念:客户端会话技术,将数据保存到客户端
2. 理解:
1. 使用步骤
1. 创建Cookie对象,指定数据
1. new Cookie(String name,String values)
2. 发送Cookie对象数据
1. response.addCookie(Cookie cookie)
3. 获取Cookie,拿到数据
1. request.getCookie()
3. 实现原理
1. 基于响应头set-cookie和请求头cookie实现
4. cookie的细节
1. 一次可不可以发送多个cookie?
1. 可以
1. 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
2. cookie在浏览器中保存多长时间?
1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
2. 设置cookie生命周期,持久化存储:
1. setMaxAge(int seconds)
1. 整数:将Cookie数据写到硬盘文件中,持久化存储。Cookie存活时间
2. 负数:默认值
3. 零:删除Cookie信息
3. cookie能不能存中文?
1. 在tomcat8之前cookie中不能直接存储中文数据
需要将中文数据转码—一般采用URL编码(%E3)
2. 在tomcat8之后cookie支持中文数据
4. cookie共享问题?
* 假设在一个tomcat服务器中,部署了多个web项目,这些web项目中能不能共享?
* 默认情况下cookie不能共享
* setPath(String path):设置cookie的获取范围,默认情况下,设置当前的虚拟目录
* 如果要共享 ,则可以将path设置为“/”
* 不同的tomcat服务器间cookie共享问题?
* setDomain(String path):设置设置一级域名相同,那么多个服务器之间cookie可以共享
* setDomain(".baidu.com"):那么tieba.baidu.com和news.baidu.com中可以共享
cookie的特点和作用
1. cookie存储数据在客户端浏览器
2. 浏览器对于单个cookie的大小有限制(4kb),以及对同一个域名下的总cookie数量也有限制(20个)

作用:
	1. cookie一般用于存储少量的不太敏感的数据
	2. 在不登陆的情况下。完成服务器对客户端的身份识别
案例:记住上一次访问时间
	1. 需求 :
		1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎首次访问
		2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
	2. 分析
		1. 	可以采用cookie来完成
		2. 	在服务器中的Servlet判断是否有一个名为lastTime的cookie
			1. 	有:不是第一次访问
			2. 	没有:是第一次访问
				1. 	响应数据:您好
				2. 	写回Cookie:lastTime

#JSP(Java Server Pages):java 服务端端页面
* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义Java代码
* 用于简化书写
1. 原理分析
1. 本质上就是一个servlet
2. jsp脚本:JSP定义Java代码的方式
1. <% 代码 %>:定义的Java代码,在service方法中,service方法中可以定义什么,该脚本就可以定义什么
2. <%! 脚本%>:定义的Java代码,在jsp转换后的Java类的成员位置
3. <%= 代码%>:定义的Java代码会输出到页面上,输出语句中可以定义什么,该脚本中就可以定义什么
JSP的内置对象
* 在jsp页面中不需要获取和创建,可以直接使用的对象
* jsp一共有9个内置对象
* request
* response
* out:字符输出流对象,可以将数据输出到页面上,和response.getWriter()类似
* response.getWriter()和out.write()的区别:
* 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。response。getWriter()数据输出永远在out.writer()之前。

##Session:
1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存到服务器端对象中。HttpSession
2. 练习:
1. HttpSession对象中
1. 获取HttpSession对象
1. HttpSession session=request.getSession();
2. 使用HttpSession对象:
1. Object getAttribute(String name)
2. void setAttribute(String name,Object value)
3. void removeAttribute(String name)
3. 原理:
* Session的实现是依赖于Cookie的
4. 细节:
1. 当客户端关闭后,服务器不关闭,两次获取Session是否为同一个?
1. 默认情况下不是
2. 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大的存活时间,让cookie持久化保存
2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
1. 不是同一个,但是要确保数据不丢失
1. session的钝化
1. 在服务器正常关闭之前,将session对象系列化到硬盘上
2. session的活化:
1. 在服务器启动之后,将session文件转化为内存中的session对象即可。
3. Session的什么时候被销毁 ?
1. 服务器关闭
2. session对象调用invalidate()
3. session默认的失效时间为30分钟
选择性配置修改

30

##session的特点:
1. session用于存储一次会话的多次请求的数据,存在服务器端
2. session可以存储任意类型,任意大小的数据
* session与Cookie区别:
* session存储数据在服务器端,Cookie在客户端
* session没有数据大小限制,Cookie有
* session数据安全,Cookie数据相对不安全

##案例:验证码

1. 案例需求:
2. 访问带有验证码的登陆页面login.jsp
3. 用户输入名,密码以及验证码
	1. 如果用户名和密码输入有误,跳转登陆页面,提示:用户名火密码错误
	2. 如果验证码输入有误,跳转登陆页面,提示:验证码输入错误
	3. 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
分析:
	* 设置request的编码
	* 获取参数Map集合
	* 获取验证码
	* 将用户信息封装到User对象
	* 判断程序生成的验证码和用户输入的验证码是否一致。从session中获取程序生成的验证码
		* 一致
			* 再判断用户名和密码是否一致
				* 正确
					* 登陆成功
					* 存储数据 
					* 跳转到success.jsp重定向
				* 不正确
					* 给提示信息
					* 跳转登陆页面



		* 不一致
			* 给用户提示信息:验证码错误request
			* 跳转登陆页面(转发)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值