栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaWeb之Servlet

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaWeb之Servlet

JavaWeb之Servlet
  • 1,关于Servlet
  • 2,第一个Servlet程序
  • 3,Servlet原理
  • 4,Mapping问题
  • 5,ServletContext对象
    • 5.1,ServletContext的应用:共享数据
    • 5.2,ServletContext的应用:获取初始化参数
    • 5.3,ServletContext的应用:请求转发
    • 5.3,ServletContext的应用:读取资源文件
  • 6,HttpServletResponse
    • 6.1,内部结构简单分类
    • 6.2,response实现下载文件
    • 6.3,response实现验证码功能
    • 6.4,response实现重定向(重点)
  • 7,HttpServletRequest
    • 代码演示一:重定向、获取前端参数
    • 代码演示二:请求转发、获取前端参数

1,关于Servlet
  • Servlet就是sun公司开发动态web的一门技术
  • Sun在这些APi中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • ①编写一个类,实现Serlet接口
      
    •  ②把开发好java类部署到web服务器中。
      

把实现了Servlet接口的Java程序叫做,Servlet


2,第一个Servlet程序

①构建一个普通Maven项目,删除src目录,在pom.xml文件中导入Servlet和JSP相关依赖:

    
    
        
        
            javax.servlet
            javax.servlet-api
            4.0.1
        
    
        
        
            javax.servlet.jsp
            javax.servlet.jsp-api
            2.3.3
        

    

②创建目录把Maven项目搭建完整

③编写一个普通类实现Servlet接口,这里我们直接继承HttpServlet。重写doGet()、doPost()。
因为Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet。(GenericServlet实现了Servlet接口,然后HttpServlet继承了GenericServlet,所以我们自己的类只需要继承HttpServlet即可,就可满足Servlet程序要求)

     public class HelloServlet extends HttpServlet {
         
          //一般要重写doGet和doPost。
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         	 System.out.println("进入了DOGET方法");  //标志
             //ServletOutputStream outputStream = resp.getOutputStream();
             PrintWriter writer = resp.getWriter(); //响应流
             writer.print("Hello,Serlvet");
         }
     
         @Override
         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //由于get,post只是请求实现的不同方式,可以相互调用,因为业务逻辑都一样
             doGet(req, resp);    //此处调用了上面的逻辑。就可以不用处理doPost(),专注于处理doGet()
         }
     }
   

④在web.xml中编写Servlet映射

为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;



    
    
        hello
        com.kuang.servlet.HelloServlet
    
    
    
        hello
        /hello     
        
    

⑤配置Tomcat

⑥启动Tomcat测试

启动Tomcat自动打开:http://localhost:8080/s1/

端口为8080,项目名路径即为/s1,会先进入index.jsp。

如果想要刚才在xml文件中映射的/hello,可以访问:http://localhost:8080/s1/hello

成功访问,打开控制台查看:

表明进入了doGet()方法。


3,Servlet原理

Servlet由Web服务器调用,Web服务器收到浏览器请求后,会:


4,Mapping问题

注意:一个Servlet可以指定一个或多个映射路径,也可以指定通用映射路径:

  • ①指定一个:

  • ②指定多个

  • ③指定通用映射路径(如使用*):

    (此时hello下的任何请求都可以映射成功,乱写也行,如)

    但要注意*前面不能加项目映射的路径,否则会访问失败。


5,ServletContext对象

①通过股骨架创建一个Maven的module,servlet-02用于演示

②把 srcmainwebappWEB-INFweb.xml 替换为如下的内容:




③创建目录把Maven项目搭建完整

④配置Tomcat

web容器(如Tomcat)在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

ServletContext可以理解为整个web应用,凌驾于所有的Servlet之上。


5.1,ServletContext的应用:共享数据

共享数据:

  • 在一个Servlet中保存的数据可以在另一个Servlet中访问到。

①通过HelloServlet向ServletContext中存数据。

public class HelloServlet extends HttpServlet {
    //ServletContext应用1:共享数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getServletContext()   获得Servlet上下文(重点)
        ServletContext servletContext = this.getServletContext();
        String username="小白";  //数据对象

        //将一个数据保存至ServletContext中,名字为:username,值为username(键值对)
        servletContext.setAttribute("username",username);
        System.out.println("hello");
    }
}

②通过GetServlet取出HelloServlet往ServletContext中存入的数据

public class GetServlet extends HttpServlet {
    //ServletContext应用1:共享数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据
        // this.getServletContext():想取存进去的东西,要先获取此ServletContext对象。HelloServlet和GetServlet拿到的都是同一个ServletContext
        ServletContext servletContext = this.getServletContext();
        String  username = (String) servletContext.getAttribute("username");  //强转成String

        //响应
        resp.setContentType("text/html");     
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("名字"+username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

③在web.xml中注册



         
    
    
        hello
        com.kuang.servlet.HelloServlet
    
    
        hello
        /hello
    
    
    
        getc
        com.kuang.servlet.GetServlet
    
    
        getc
        /getc
    

④启动Tomcat

启动之后自动打开如下页面:

直接进入/getc,发现名字后面是null:

这是因为我们还没有往ServletContext里存数据,就访问了/getc去取数据,所以为null。)

所以正确的方式为先访问/hello

这时控制台会输出 hello,因为存数据之后执行了HelloServlet中的输出语句:如下图

此时再访问/getc就会成功拿到存入ServletContext中的共享数据。

5.2,ServletContext的应用:获取初始化参数

①再XML中配置一些初始化参数


    
        url
        jdbc:mysql://localhost:3306/mybatis
    

②ServletContext类对象调用getInitParameter()获取初始化参数

public class ServletDemo03 extends HttpServlet {
    //ServletContext应用2:获取初始化参数
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String url = servletContext.getInitParameter("url");//可以获取web.xml中初始化的参数

        //PrintWriter writer = resp.getWriter();
        //writer.print(url);  也可以使用如下的方式,一步到位
        resp.getWriter().print(url);       //把String类型的url打印出来看一下
    }

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

③在web.xml中注册


        gp
        com.kuang.servlet.ServletDemo03
    
    
        gp
        /gp
    

④启动Tomcat成功访问到参数内容

5.3,ServletContext的应用:请求转发

①编写Servlet

getRequestDispatcher():获取请求转发,参数为String类型的path,此参数即需要转发到的地址。
比如参数"/gp",“/”表示当前项目,/gp:转发到gp请求。

最后还需要调用forword()实现请求转发。

public class ServletDemo04 extends HttpServlet {
    //ServletContext应用3:请求转发
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("进入了ServletDemo04");  //标志
        RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp"); //转发的请求路径
        requestDispatcher.forward(req,resp);  //调用forward实现请求转发(通过getRequestDispatcher转发到另一个页面)
    }

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

②在web.xml中注册

 
        sd4
        com.kuang.servlet.ServletDemo04
    
    
        sd4
        /sd4
    

③启动Tomcat,访问/sd4,效果如下图所示:

请求到/sd4,但通过请求转发去了另一个页面/gp,转发的时候路径是没有变的(和重定向不同,重定向路径会变)。

请求转发机制的通俗理解:
A想拿到C的资源,但A当前只能找到B,B可以去找C拿,C返回给B之后,B再转发给A。此过程中A始终和B交互,没有看到C,所以路径不变。


(而重定向是:A找到B告诉B它需要某个资源,但此资源只要C处才有,这时B告诉A让它去找C拿,于是A又去找C)

5.3,ServletContext的应用:读取资源文件

读取资源文件需要一个文件流,先在resources目录下里创建db.properties文件,文件内容如下:

Javaweb之前读取配置文件的方式是:

  • 使用load()方法并放入相应文件流作为参数。

以上方式中需要涉及到文件的绝对地址,但在Web应用需要走服务器,无法保证文件绝对地址,因此需要要观察target目录,看文件会生成在web的哪个地方。

WEB-INF目录下的classes目录包含main中java目录和resources目录中文件生成的目录,也称之为classpath(类路径)


①编写Servlet
先获取ServletContext对象,用此对象调用getResourceAsStream()

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");//路径相对于生成的target目录,第一个/表示当前web项目不可省略
        Properties properties = new Properties();
        properties.load(is);  //把流加载进去
        String user = properties.getProperty("username");
        String pwd = properties.getProperty("password");

        resp.getWriter().print("user:"+user+" pwd:"+pwd);
    }

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

②到web.xml文件中注册


        sd5
        com.kuang.servlet.ServletDemo05
    
    
        sd5
        /sd5
    

③启动Tomcat,访问/sd5


web服务器接收到客户端的http请求后,
会针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse。

  • 要获取客户端请求过来的参数,使用HttpServletRequest
  • 要获取客户端响应的一些信息,使用HttpServletResponse

6,HttpServletResponse

HttpServletResponse extends ServletResponse

6.1,内部结构简单分类

其中:

负责向浏览器发送数据的方法:

 servletOutputstream getOutputstream() throws IOException;
 Printwriter getwriter() throws IOException;

负责向浏览器发送响应头的方法,比如:

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String varl,long var2)
void addDateHeader(String var1,long var2)
void setHeader(String var1,String var2);
void addHeader(String var1,String var2);
void setIntHeader(String var1,int var2);
void addIntHeader(String varl,int var2);

响应的状态码

6.2,response实现下载文件

1,向浏览器输出消息(前面一直在讲,此处不再赘述)

2,下载文件:

  • ①先获取下载文件的路径
  • ②下载的文件名
  • ③想办法让浏览器支持下载我们需要的资源
  • ④获取下载文件的输入流
  • ⑤创建缓冲区
  • ⑥获取OutPutStream对象
  • ⑦将FileOutputStream流写入buffer缓冲区
  • ⑧使用OutputStream对象将缓冲区中的数据输出到客户端

编写Servlet程序:

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1,要获取下载文件的路径
        String realPath1=this.getServletContext().getRealPath("/海湾.jpg");
        System.out.println(realPath1);  //F:programmingJavanotesapache-tomcat-7.0.93webappsr海湾.jpg
        //注意ServletContext是由Tomcat创建的,所以/海湾.jpg是去Tomcat的webapps下找,找不到
        
        //此处把路径(target下的文件路径)写死
        String realPath = "F:\javawebcode\javaweb\response\target\classes\海湾.jpg";
        System.out.println("下载的文件的路径为:"+realPath);  //下载的文件的路径为:F:javawebcodejavawebresponsetargetclasses海湾.jpg
        //2,下载的文件名是啥?
        String fileName = realPath.substring(realPath.lastIndexOf("\") + 1); //注意此处很巧妙。\转义了一个,最后+1表示截取/后面的下一个位置到最后
        //3,设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西(设置浏览器行为,使用response)
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));  //URLEncoder.encode(fileName,"UTF-8"))转码使中文名文件可正常显式
        //4,获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        //5,创建缓冲区
        byte[] buffer=new byte[1024];
        int len;
        //6,获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
        //7,将FileOutputStream流写入到bufer缓冲区
        while ((len=in.read(buffer))!=-1){
            os.write(buffer,0,len);
        }
        //8,使用OutputStream将缓冲区中的数据输出到客户端!
        os.close();
        in.close();
    }

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

web.xml中注册


        filedown
        com.kuang.servlet.FileServlet
    
    
        filedown
        /down
    

启动Tomcat测试访问

成功下载

6.3,response实现验证码功能

了解

编写Servlet

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器五秒自动刷新一次
        resp.setHeader("refresh","3");

        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D graphics = (Graphics2D) image.getGraphics();  //相当于一支笔
        //设置图片背景色
        graphics.setColor(Color.white);   //使用画笔画出白色背景
        graphics.fillRect(0,0,80,20);
        //给图片写数据
        graphics.setColor(Color.BLUE);   //给画笔换颜色
        graphics.setFont(new Font(null,Font.BOLD,20));
        graphics.drawString(makeNum(),0,20);  //把随机数画成一个字符串,图片上就有了数据

        //告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/jpeg");

        //网站存在缓存,此处不让浏览器缓存
        resp.setDateHeader("expires",-1);   //设为-1
        resp.setHeader("Cache-Control","no-cache");     //缓存策略为不缓存
        resp.setHeader("Pragma","no-cache");

        //把图片写给浏览器
       ImageIO.write(image,"jpg",resp.getOutputStream());


    }

    //生成随机数
    private String makeNum(){
        Random random = new Random();
        String num= random.nextInt(9999999)+"";   //七位数的验证码
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            sb.append(0);         //生成的数字不足七位时使用0填充。
        }
        String s=sb.toString()+num;    //保证是七位
        return num;
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml中注册

 
        ImageServlet
        com.kuang.servlet.ImageServlet
    
    
        ImageServlet
        /img
    

启动Tomcat测试:

屏幕中间出现一个七位数的验证码,五秒刷新一次。

6.4,response实现重定向(重点)


用户登陆成功的跳转,就是一个重定向。

重定向使用的方法是:

  • public void sendRedirect(String location) throws IOException;

①编写index.jsp


<%@ page contentType="text/html; charset=UTF-8"%>

Hello World!

<%--这里提交的路径,需要寻找到项目的路径--%> <%--pageContext.request.contextPath()代表当前项目--%>
用户名:
密码:

②编写Servlet

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.sendRedirect("/r/img");   //重定向  /r是当前项目
    }

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

③web.xml中注册


        RedirectServlet
        com.kuang.servlet.RedirectServlet
    
    
        RedirectServlet
        /red
    

④启动Tomcat测试


启动Tomcat,进入路径/red,自动跳转至/img

7,HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法可以获取客户端的所有信息。


HttpServletRequest应用主要有:

  • 重定向、获取前端传递的参数,请求转发…

两个常用方法:

  • getParameter(String s) 返回String型
  • getParameterValues(String s) 返回String[ ]型

代码演示一:重定向、获取前端参数

①编写success.jsp(跳转成功的页面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


success

②编写Servlet

public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");//从请求里获取参数
        String password = req.getParameter("pwd");
        System.out.println(username+":"+password);
        //重定向(注意要路径问题,否则会404,404表示代码正确,页面不对)
        resp.sendRedirect("/r/success.jsp");
    }

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

③配置web.xml


        request
        com.kuang.servlet.RequestTest
    
    
        request
        /login
    

④启动Tomcat测试

数据提交后,自动跳转:

查看控制台,发现成功从请求中获取参数

重定向的时候一定要注意路径的问题,否则会报404!!!


代码演示二:请求转发、获取前端参数

①编写Servlet

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");  //防止输出乱码
        resp.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String[] hobbies = req.getParameterValues("hobby");   //获取多选框多个值
        System.out.println("===========================");
        //后台接收中文乱码问题
        System.out.println(username);
        System.out.println(pwd);
        //System.out.println(Arrays.toString(hobbies));
        System.out.println(hobbies);
        System.out.println("===========================");

        //通过请求转发,这里的/success.jsp中的/代表当前的web应用
        req.getRequestDispatcher(req.getContextPath()+"/success.jsp").forward(req,resp);  //此处路径不写死
    }

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

注意把握请求转发(307)和重定向(302)的区别!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/880310.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号