Servlet学习

一、Servlet的创建与使用

(1)IDEA创建项目

首先创建Java EE项目,勾选Web Application,说明是Web应用,会添加Servlet需要的jar包。
在这里插入图片描述
IDEA配置Tomcat
在这里插入图片描述
在这里插入图片描述

(2)Servlet实现

在src目录下创建存放servlet的包,然后创建一个servlet类;

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //打印内容
        System.out.println("创建servlet");
    }
}

主要有三个点:

  • 实现Servlet规范(3种方式)
  • 重写Service() 方法(ctrl + o)
  • 设置请求路径(注解@WebServlet)

三种方式:

//继承HttpServlet方式创建(主要)
@WebServlet(value = {"/ser01", "/ser001"})	//可以设置多个请求路径到这个servlet
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("继承HttpServlet方式创建servlet");
    }
}
//继承GenericsServlet方式创建servlet,需要实现全部方法
@WebServlet("/ser02")
public class Servlet02 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("继承GenericsServlet方式创建servlet");
    }
}
//实现Servlet接口方式创建servlet
@WebServlet("/ser03")
public class Servlet03 implements Servlet { 
         @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("实现Servlet接口方式创建servlet");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {

    }
}

除了使用service()调用之外,还有重写doGet和doPost方法可以处理请求。一般都是get方法,前端是form表单提交的话可以指定post方法。get方法会把参数显示在url的?后面,post方法不会显示。

    //重写doGet()方法和doPost()方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Get请求...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Post请求...");
    }

(3)Servlet生命周期

在这里插入图片描述

@WebServlet("/ser05")
public class ServletLive extends HttpServlet {

    //服务器自动调用,当有请求到达servlet时,就会调用
    //可调用多次
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("调用了service方法");
    }
    
    // 初始化方法,服务器自动调用,当请求到达Servlet容器时,
    // 判断该Servlet对象是否存在,不存在则创建实例并初始化
    @Override
    public void init() throws ServletException {
        System.out.println("调用了init方法");
    }
    
    //销毁方法
    //只调用一次
    @Override
    public void destroy() {
        System.out.println("调用了destroy方法");
    }
    
}

二、HttpServletRequest对象

在service(HttpServletRequest req, HttpServletResponse resp)方法中,有两个参数,一个是请求对象request接收浏览器传过来的请求信息;另一个是响应对象response用来存放响应信息给浏览器。

这节主要是学习请求对象的一些常用方法和使用。

(1)常用方法

@WebServlet("/req01")
public class Servlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* 常用方法 */
        //获取请求时的完成路径,从http开始,到?结束
        String url = req.getRequestURL() + "";

        //获取请求时的部分路径,从项目的站点名开始,到?结束
        String uri = req.getRequestURI();

        //获取请求的参数字符串,从?后面开始
        String params = req.getQueryString();

        //获取请求方法,get/post
        String method = req.getMethod();

        //获取当前的协议版本,http/1.1
        String protocol = req.getProtocol();

        //获取项目的站点名,对外访问路径
        String webApp = req.getContextPath();

        /*  获取请求参数的方法  */
        //获取指定名称的参数值,返回字符串
        String name = req.getParameter("name");
        String psw = req.getParameter("psw");

        //获取指定名称的所有参数值(复选框),返回字符串数组
        String[] hobbys = req.getParameterValues("hobby");
//        if (hobbys != null && hobbys.length > 0) {
//            for (String hobby : hobbys) {
//                System.out.println("爱好:" + hobby);
//            }
//        }
        System.out.println(hobbys.toString());
    }
}

(2)请求乱码问题

由于现在的request属于接收客户端的参数,所以有其默认的语言编码,而在解析过程中默认使用的编码为ISO-8859-1(此编码不支持中文),所以解析时会出现乱码。解决方法是1. 设置request中的编码格式,告诉服务器以何种方式来解析数据;2. 或者在接收到乱码数据以后,通过相应的编码格式还原。

Tomcat8以上版本
Get请求 不会乱码
Post请求 会乱码

解决:设置服务器解析编码的格式

request.setCharacterEncoding(“UTF-8”)

@WebServlet("/req02")
public class Servlet02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求的编码格式
        req.setCharacterEncoding("UTF-8");

        String uname = req.getParameter("uname");
        String upwd = req.getParameter("upwd");
        System.out.println(uname);
    }
}

(3)请求转发

一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的URL地址不会改变,得到响应后,服务器再将响应发送给客户端,从始至终只有一个请求发出。

req.getRequestDispatcher(“login.jsp”).forward(req, resp);

@WebServlet("/req03")
public class Servlet03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        System.out.println("Servlet03 name :" + name);

        //请求转发给Servlet04
//        req.getRequestDispatcher("req04").forward(req, resp);

        //请求转发到JSP页面
//        req.getRequestDispatcher("login.jsp").forward(req, resp);

        //请求转发到HTML页面
//        req.getRequestDispatcher("login.html").forward(req, resp);
    }
}

请求转发跳转

  • request.getRequestDispatcher(url).forward(request, respond);
  • 可以让请求从服务器跳转到客户端(或者跳转到指定的Servlet)
  • 服务端行为

特点:

  1. 地址栏不发生改变
  2. 服务端行为
  3. 只有一个请求

(4)request作用域

因为参数中的HttpServletRequest req是一个对象,所以可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。可以在请求转发的过程中使用request来传递/共享数据

req.setAttribute( key , value );

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("servlet05");

        //设置域对象内容
        req.setAttribute("name", "admin");
        req.setAttribute("age", 18);
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        req.setAttribute("list", list);

        //请求转发给Servlet06
        req.getRequestDispatcher("req06").forward(req, resp);

        //请求转发给JSP,并通过域对象传递数据
        //req.getRequestDispatcher("index.jsp").forward(req, resp);
    }

Servlet获取域对象内容:

req.getAttribute( key ); //返回Object对象,要强转

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("servlet06");
        //获取域对象内容,返回Object对象,要强转
        String name = (String) req.getAttribute("name");
        Integer age = (Integer) req.getAttribute("age");
        List<String> list = (List<String>) req.getAttribute("list");
    }

三、HttpServletResponse对象

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。
request对象:获取客户端数据
response对象:向客户端发送数据。

HttpServletResponse的主要功能用于服务器对客户端的请求进行响应,将Web服务器处理后的结果返回给客户端。service()方法中形参接收的是HttpServletResponse接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头、发送响应状态码的方法。

(1)响应数据

接收到客户端请求后,可以通过该对象直接进行响应,响应时需要获取输出流,有两种形式:

getWriter() 获取字符流(只能响应回字符)
getOutputStream() 获取字节流(能响应一切数据)

不能同时被使用

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取字符输出流
        PrintWriter writer = resp.getWriter();
        //输出数据
        writer.write("hello1");

        //字节输出流
//        ServletOutputStream out = resp.getOutputStream();
//        //输出数据
//        out.write("hello2".getBytes());
    }

(2)响应乱码问题

因为服务器响应的数据会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。

对与getWriter()方式获取的字符流,响应中文必定出乱码,默认使用ISO-8859-1格式。
对于getOutputStream()方式获取的字节流,响应中文时,由于本身就是传输的字节,所以可能出现乱码。

无论如何都应该设置好服务器和客户端使用的编码格式,以确保数据正确显示。

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //设置服务端的编码格式
        resp.setCharacterEncoding("UTF-8");

        //设置客户端的编码格式
        resp.setHeader("content-type","text/html;charset=UTF-8");

        //同时设置
//        resp.setContentType("text/html;charset=UTF-8");

        //获取字符输出流
        PrintWriter writer = resp.getWriter();
        //输出数据
        writer.write("<h2>你好</h2>");
        
    }

(3)重定向

重定向是一种服务器指导,客户端的行为。客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址,当客户端收到响应后,会马上自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//name在cdx02用getParameter拿不到
        String name = req.getParameter("name");
        
        //重定向到cdx02
        resp.sendRedirect("cdx02");
    }

(4)请求转发与重定向的区别

请求转发重定向
req.getRequestDispatcher().forward()resp.sendRedirect()
一次请求,数据在request域共享两次请求,不共享
服务器端行为客户端行为

四、 Cookie对象

Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只需保存在客户端,或者在客户端处理的数据,放在本地的计算机上。

不需要通过网络传输,因而提高网页处理的效率,并且能够减少服务器的负载。

(1)创建与发送

添加到response对象中

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //创建Cookie对象
        Cookie cookie = new Cookie("name", "admin");
        //发送Cookie对象
        resp.addCookie(cookie);
    }

(2)获取

在服务器端只提供了一个getCookies()方法获取客户端回传的所有cookie组成的一个数组,如果需要获取单个cookie则需要通过遍历,getName获取名称,getValue获取值。

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //获取Cookie
        Cookie[] cookies = req.getCookies();

        if (cookies != null && cookies.length > 0) {
            for (Cookie c : cookies) {
                String name = c.getName();
                String value = c.getValue();
                System.out.println(name + "-" + value);
            }
        }

    }

(3)设置到期时间

用到的时候再看把。。

五、HttpSession对象

在这里插入图片描述

(1)获取和方法

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Session
        HttpSession session = req.getSession();

        //获取会话标识符       JSESSIONID唯一标识符
        String id = session.getId();
        System.out.println(id);

        //获取Session的创建时间
        System.out.println(session.getCreationTime());

        //获取最后一次访问时间
        System.out.println(session.getLastAccessedTime());

        //判断是否是新的Session对象
        System.out.println(session.isNew());

    }

(2)域对象

类似request对象,可以存放数据,但是范围更大,使用重定向后,在新的servelt都能用session.getAttrubute拿到数据。

@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session域对象
        HttpSession session = req.getSession();

        //设置域对象
        session.setAttribute("uname", "admin");
        session.setAttribute("upwd", "123456");

        //移除session域对象
        session.removeAttribute("upwd");

        //request域对象
        req.setAttribute("name", "zhangshan");

        //请求转发
//        req.getRequestDispatcher("session.jsp").forward(req, resp);

        //重定向
        resp.sendRedirect("session.jsp");
    }

六、ServletContext对象

每个Web应用都有且仅有一个ServletContext对象,又称Application对象,从名称中可知,该对象是与应用程序相关的。在Web容器启动的时候,会为每个Web应用程序创建一个对应的Servlet对象。

该对象有两大作用,第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;第二,该对象中保存了当前应用程序相关信息。例如可以通过getServerInfo()方法获取当前服务器信息,getRealPath(String path) 获取资源的真实路径等。

 @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过request对象获取
        ServletContext servletContext = req.getServletContext();

        //通过session对象获取
        ServletContext servletContext1 = req.getSession().getServletContext();

        //通过ServletConfig对象获取
        ServletContext servletContext2 = getServletConfig().getServletContext();

        //直接获取
        ServletContext servletContext3 = getServletContext();

        //常用方法
		用到再看把。。。。
    }

七、文件上传和下载

(1)上传

文件上传涉及到前台页面的编写和后台服务器代码的编写,前台发送文件,后台接收并保存文件。

前台页面:
在做文件上传的时候,会有一个上传文件的界面,首先需要一个表单,并表单的请求方式为POST,其次我们的form表单enctype必须设置为"multipart/form-data",说明表单的类型为文件上传表单。默认情况下这个表单的类型是"application/x-www-form-urlencoded",不能用于文件上传。

<form method="post" enctype="multipart/form-data" action="uploadServlet">
    姓名:<input type="text" name="uname" > <br>
    文件:<input type="file" name="myfile" ><br>
    <button>提交</button>
</form>

后台实现:
使用注解@MultipartConfig将一个Servlet标识为支持文件上传。Servlet将multipart/form-data的POST请求封装成Part,通过Part对上传的文件进行操作。

@WebServlet("/uploadServlet")
@MultipartConfig    //文件上传,要设置该注解
public class UploadServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("文件上传...");
        //设置请求的编码格式
        req.setCharacterEncoding("UTF-8");

        //获取普通表单项
        String uname = req.getParameter("uname");
        System.out.println(uname);

        //获取Part对象,Servlet将 multipart/form-data 的POST请求封装成Part对象
        Part part = req.getPart("myfile");
        //通过Part对象获得上传的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println(fileName);

        //得到文件存放的路径
        String filePath = req.getServletContext().getRealPath("/");
        System.out.println(filePath);
        //上传文件到指定目录
        part.write(filePath + "/" + fileName);
    }
}

(2)下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值