(三)浅谈Servlet

Servlet是什么

   在之前介绍JSP的时候,曾经引用过百度百科中对JSP的一个简单定义,其中有一句是这样描述的:JSP其根本是一个简化的Servlet设计 ,那么Servlet又是什么呢。

Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。—— Wikipedia

  这是维基百科上关于Servlet的简单描述,从这里可以看出关键的作用动态Web内容 ,这个便是Servlet最基本的作用,用于生成动态的Web内容。而Servlet本身是一套极其复杂精妙的设计,其中涉及到了方方面面的知识,诸如Java反射,设计模式,Servlet规范等,在本文中难以详细介绍其原理。所以如果有读者对Servlet原理感兴趣请移步 Servlet工作原理解析 ,其中对整个Servlet的工作原理进行了详细的介绍。而之前提到的JSP则是一个特殊的Servlet,当Web容器(Tomcat,Jetty等)第一次接收到对该JSP页面的请求时,会自动将JSP文件编译成Java的Class字节码文件并且进行装载,初始化。这个过程就将JSP转换为Servlet了,之后所有的工作流程便于Servlet的工作流程一致了。所以,从本质上来说,JSP就是一种特殊的Servlet。

编写Servlet

   上文中提到了JSP的缺点便是无法做到业务逻辑及数据与视图分类,而通过直接编写Servlet将可以解决这个问题。下面我们继续对上次的JSP工程进行修改,编写一个简单的登录页面,其中便可以使用Servlet处理登陆的业务逻辑。
   首先需要在 src 目录中新建一个类,该类要继承 HttpServlet ,Servlet的名称没有固定要求
新建Servlet
   这样便新建好了一个新的Servlet,接下来,要让我们的JavaWeb容器识别并加载这个Servlet就需要对这个新建的Servlet进行注册,而注册的方式便是将该Servlet配置到 web.xml 配置文件中。Servlet有2种注册形式,分别是在容器启动时便进行装载但是这种Servlet并不能被我们的浏览器访问到,而第二种便是与URL进行绑定,当有请求发送到这个Servlet时便会自动加载这个Servlet。我们使用第二种方式配置,因为我们需要让我们的登录请求发送到这个Servlet进行处理。在web.xml中的 web-app 标签中加上这样一段配置

    <servlet>
        <servlet-name>Login</servlet-name>
        <servlet-class>com.geekylx.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Login</servlet-name>
        <url-pattern>/Login.do</url-pattern>
    </servlet-mapping>
  • servlet:配置一个Servlet
  • servlet-name:Servlet名,用以标记这个Servlet
  • servlet-class:Servlet对应的Java类
  • url-pattern:Servlet绑定的URL(相对于根目录)

注:一个Servlet必须同时配置servlet及servlet-mapping,并且其中的servlet-name要保持一致

   至此便完成了对Servlet的注册工作。编写这个Servlet的作用是让这个Servlet处理登录过程中的业务逻辑,那么现在需要对index页面进行修改,需要展示账号、密码的输入框以及提交按钮,这些都需要在一个表单中,通过post方式提交至Servlet进行处理。

    <form action="Login.do" method="post">
        <label>账号:</label><input type="text" name="username" />
        <label>密码:</label><input type="password" name="password">
        <input type="submit" value="提交">
    </form>

  在index.jsp中加入这样一段代码,这里构造了一个表单,在点击提交按钮之时便将username及password通过post方式发送至后台的Login.do页面,也就是Servlet绑定的那个URL。那接下来的工作便是在LoginServlet中获取这两个参数并且判断账号密码是否正确了。当判断出用户账号密码是否正确后需要将结果进行展示,这里就需要将请求转发给另一个页面,并且告知该页面登录结果,由这个新的页面展示出登录的结果。那么再编写一个jsp页面用来展示登陆的结果。

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username"); //获取参数username
        String password = req.getParameter("password"); //获取参数password
        System.out.println(username + "--" + password);
        boolean loginResult = ("test".equals(username) && "123456".equals(password)); //简单判断是否符合要求
        System.out.println(loginResult);
        req.setAttribute("result", loginResult);  //将结果放置在HttpServletRequest对象中,用于在展示结果的页面中取出
        req.getRequestDispatcher("LoginResult.jsp").forward(req, resp); //将请求转发给LoginResult页面用于展示结果
    }

  重写LoginServlet中的doPost方法,用于处理接收到的post请求,HttpServletRequest对象中封装了本次请求的信息,可以从中获取参数也可以使用setAttribute()方法将值存入HttpServletRequest中,该对象的生命周期为本次请求。getRequestDispatcher().forward()方法将本次请求转发给另外的Servlet,属于服务器内部转发,不会改变HttpServletRequest对象和HttpServletResponse对象。
   LoginResult.jsp用于展示登录结果,它将保存在HttpServletRequest中的结果取出用于展示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>结果</title>
</head>
<body>
    <%
        boolean result = (boolean) request.getAttribute("result");  //获取HttpServletRequest对象中存储的结果
        String loginResult = result ? "成功" : "失败";
    %>
    <h1>本次登录:<%=loginResult %></h1>
</body>
</html>

  至此,代码编写完毕。现在运行一下查看一下效果。

失败样例:username:myname,password:123456

错误账号密码

控制台打印

失败页面

成功样例:username:test,password:123456

成功样例

成功控制台输出

成功页面

结语

   通过短短几行代码就完成了一个最简单的登录功能,是不是很简单?在实际的项目中用到的就不再是简单的字符串比较了,而是会涉及到编码,数据库操作等众多复杂的业务逻辑。但是思路却是一致的,都是在Servlet中将业务逻辑进行处理之后再通过请求转发等方式返回结果页面,感兴趣的读者可以自行将该项目扩展。那么通过这样一个小示例简单的展示了如何使用Servlet,但这只是冰山一角,Servlet还有许多用法这里不再做介绍。
   很多读者应该注意到了,无论是使用JSP还是Servlet,每一个请求都必然会返回一整个页面给浏览器。这显然在许多场景下是不适用的。很多网站我们在进行注册的时候会实时提醒用户名是否重复,使用搜索引擎搜索时会根据输入实时弹出可能的关键字。这些操作显然不是每次都从服务器拉取整个页面再进行展示可以做到的。并且,在进行开发的时候前端和后端并不能完全分离开发,前端总是需要给后端留下数据展示的位置,后端总是要将前端的页面转成后端模板文件,这显然不利于两边独立的开发,效率大打折扣。那么该如何实现前后端完全分离呢?如何做到每次请求只传输少量的数据而不是整个页面呢?从下一篇文章开始,笔者将一步步开发出前后端完全分离的web项目。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值