文章目录
我的学习路线
——本次学习的简单说明
本次的学习分为九节
注:点击题目会跳转到其他博客链接
Day1:JSP的入门&环境的配置&Tomcat的注意点
Day2:简单项目的创建和基本的功能的实现(打war包,共享项目)
Day3:JSP基础语法
Day4:JSP 九大内置对象及四个作用域
Day5:JavaBean 组件
Day6:Servlet 开发
Day7:EL 表达式
Day8:Jsp 自定义标签
Day9:Jsp 标准标签库持续更新中:新的博客写完会加链接
下面是Day6的学习
Servlet的引入
菜鸟学习,网址如下:www.runoob.com
1、Servlet是什么?
2、Servlet架构
很明显的看到,在这个架构中,Servlet是在中间层的,用户通过对网页进行一些操作,Http会发送请求一个请求给Servlet,Servlet作为中间层,把接收到的数据进行处理,上面的图显示的是和数据库进行交互处理。
3、Servlet任务
这个就是处理的整个过程,cookies的学习已经在九大内置对象里面学了。
4、Servlet包
Servlet的实现
1、代码实现
创建一个Servlet类,代码如下,命名为HelloWorld
package One;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet 是请求的处理者,请求分两种,一张是get,一种是post
*/
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
//假如网页中的请求是get类型的请求的时候,就让post处理
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("GBK");
PrintWriter out=response.getWriter();//向页面写东西
out.println("<html>");
out.println("<head><title>你好,大家好</title><head>");
out.println("我是一个点,我爱学习,学习爱我!");//输出在页面上
out.println("</html>");
out.close();//关闭页面的输入流
}
}
web.xml中的配置如下,注意千万别乱改命名!!!不然没法匹配成功的。
通过地址,确定名字,寻找相同的名字,通过名字,确定类。
效果如下:
没有指定 编码方式,出来的效果很惨,直接乱码了
改成GBK的编码就可以了
2、请求类型
这里的请求是get请求还是post请求呢?其实很简单判断的,直接看最后进入的接口是哪一个,加上一行代码,如下
效果
所以,很明显的看到,默认的浏览器给的请求是get请求,我们通过doGet进入,然后调用doPost进行方法的实现!一般自己开发的时候,是用post请求的,如果遇到get请求的,就用这种方法拿去让post进行处理,所以只写post中的处理就行了!
Servlet生命周期
——单实例,多线程
Servlet的生命周期如下,分为四个阶段,阶段是有序的。
1、Servlet的类加载
启动的时候类是会自动加载的,这个就是整个过程中的第一个步骤。
2、Servlet的类实例化
第一次访问的时候,类就是实例化,第一次的实例化会调用init方法。init是会执行一次的!!!
3、Servlet的类服务
当用户进行请求的时候,这里就会产生服务的需求,这里的服务,其实代表的就是doGet和doPost,然后这两个方法对客户端收到的信息进行处理。
4、Servlet的类销毁
代码实现
LifeServlet的代码如下:
package One;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LifeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是用于服务的");
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是用于服务的");
}
@Override
public void destroy() {//销毁
// TODO Auto-generated method stub
super.destroy();
}
@Override
public void init() throws ServletException {
// TODO Auto-generated method stub
super.init();//初始化
}
}
配置web.xml
想看效果的,直接在每个方法里面加一个输出(System.out.print(“我正在执行。。。”)),每次操作的时候,去控制台看一下,就能看到Servlet的进行的程度了。
客户端跳转VS服务端跳转
在Servlet中获取session,application 客户端跳转:
response.sendRedirect(“目标地址”)
服务器跳转:RequestDispatcher rd=request.getRequestDispacher(“目标地址”);rd.forward(request,response);
1、客户端跳转的实现
首先创建一个Servlet
RedirectServlet的代码如下
package Two;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class RedirectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public RedirectServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("requestKey", "requeset值");//只是重定向了,没有取到值的
HttpSession session=request.getSession();//获取session
session.setAttribute("sessionKey", "session值");
ServletContext application=this.getServletContext();
application.setAttribute("applicationKey", "application值");
//一般的步骤是重定向,再进行取值!
//上面都是设置值的部分
response.sendRedirect("target.jsp");//客户端跳转,重定向,response是用于传回的
}
}
配置web.xml中的跳转的设置
如图,客户端的对Servlet的访问的接口是redirect,所以我们是可以直接访问resirect,下面创建一个target.jsp,用于访问resirect.jsp之后的跳转
target.jsp的代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>目标地址</h1>
request值:`<%=request.getAttribute("requestKey") %>`<br/>
session值:<%=session.getAttribute("sessionKey") %><br/>
application值:<%=application.getAttribute("applicationKey") %><br/>
</body>
</html>
然后网址访问
运行起来RedirectServlet,可以看到如下的界面
此时就实现了页面的跳转,我们通过web.xml中的配置,找到java文件,java文件通过doGet的接口进入,然后实现doPost的方法,之后在doPost的方法中重定向和取值,最后重定向和客户端跳转,,实现target.jsp的运行。
2、服务器跳转
服务器跳转是内部转发的
ForwardServlet的代码如下
package Two;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 下面是客户端跳转的实现
* @author Administrator
*
*/
public class ForwardServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ForwardServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("requestKey", "requeset值");
HttpSession session=request.getSession();//获取session
session.setAttribute("sessionKey", "session值");
ServletContext application=this.getServletContext();
application.setAttribute("applicationKey", "application值");
RequestDispatcher rd=request.getRequestDispatcher("target.jsp");
rd.forward(request, response);//服务器跳转//转发
}
}
配置web.xml
效果
3、两者区别:
服务器端跳转和客户端跳转的区别 最大区别就是服务器端跳转是可以直接获得request的值的
JSP实现用户登录界面强烈推荐看看
由于内容挺多的,就不放在这里了,然后单独写了一个博客,这个是对上面学习的知识的实现和巩固,强烈的推荐看一下 博客链接如下
登录界面
Servlet过滤器
过滤用户请求
- 这个主要是过滤一些非法请求的,比如上面写的登录界面的,我们是需要登录了才能到主页面,什么是主页面呢?
- 主页面就是用户登录成功了之后显示的页面,按照我们写的那个代码,目的是用户在登录页面登录,然后submit对表单的数据进行提交,到web.xml中找到后台的Servlet,通过后台的Servlet对用户的账户密码与数据库中的数据进行匹配,匹配成功了以后,再实现页面的跳转,到达我们的注界面,就像QQ一样,登录了,才能到达聊天的界面。
- 但是现在有一个问题,就是我们是可以通过网址,直接访问主页面的,那登录的那个还有什么意义呢?这样一些不法人员就能直接到主页面去使用一些操作了
- 所以现在要做的,要解决的,就是让用户想要到主界面,必须是登录进去的,不能直接对主界面进行访问
首先创建一个java文件
代码如下
package filtr;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class LoginFilter implements Filter{
@Override
/*
* 过滤器销毁的方法
* @see javax.servlet.Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
@Override
/*
* 过滤器的核心方法
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
//两个request是不一样的,所以要进行一下强转
HttpServletRequest request=(HttpServletRequest) servletRequest;
Object o=request.getAttribute("currentUser");
String path=request.getServletPath();//获取用户请求的路径
//如果用户请求的路径是login,说明用户是从登陆界面进行访问的
if(o==null&&path.indexOf("login")<0){
request.getRequestDispatcher("login.jsp").forward(servletRequest, servletResponse);
}else {
//否则就继续往下执行
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
/*
* 过滤器的初始化方法
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
值得注意的是,这个是要实现filter的方法的,就像我们写线程一样,线程的编码,有两种方法,一种是继承Thread,然后重写线程的方法,另一种便是实现Runnable接口,实现其中的run方法,就像下面的代码一样。
所以,我们的这里的原理其实和上面的线程的原理是一样的,都是实现接口,锅炉器是实现Filter接口中的三个方法。
下面是配置web.xml中的过滤器
值得注意的是,这个的书写的方式和Servlet的书写方式是相当的类似的,还有==*/==的意思是,过滤所有的请求
具体的过滤是什么样的呢?
主要是看这个
每次的登录,带来的效果都能产生一个currentServlet对象,这个对象可能是空的(登录失败),也可能是有一个账户和密码的属性在这个对象里(登录成功)。所以不管怎么样,这个对象都是存在的,因为我们的LoginServlet的执行的依据是login这个界面的submit提交按钮对form表单中的login进行请求,到web.xml文件中找到LoginServlet,然后再执行后台的LoginServlet,而currentServlet这个对象的产生,又是依据LoginServlet的执行的,究其本源,想要产生currentServlet这个对象,就必须在login这个页面进行登录的submit。
最后的效果是
访问主页面的地址,会自动跳转到登录界面,这样我们就能过滤到非法的用户请求了,然后看一下登录的效果
这个主页的jsp如下