JAVA Web_定义Servlet_处理POST请求【练习】
题目
有一个登录页面(login.html),其登录表单的HTML代码如下:
</form action="doLogin" method = "post">
用户名:<input type="text" name="userName"><br>密码: <input type="password" name="pwd"><br><input type="submit" value="登录">
</form>
定义一个Servlet(类名自定义)实现登录验证,具体要求如下:
1、获取表单中的用户名密码;(30%)
2、验证登录用户提交的用户名是否为xx,密码为123456,如果验证通过,则将用户名添加为HttpSession的一个属性,再将请求内部派发到home.html;(60%)
3、如果用户名和密码不正确,则将请求重定向到login.html;(10%)
不知大家现在处理POST请求的功力如何。如今,正巧有一题,不妨一试?
前文链接:JAVA Web_定义Servlet2_学生登录验证Servlet-CSDN博客 - POST请求处理
JAVA Web_定义Servlet_1 欢迎考生-CSDN博客 - GET请求处理
经过前文的铺垫,代码也算是入门。接下来,我们刷题的节奏可要提起来了:
目录
题目
分析题意:
处理POST请求:
获取获取表单中的用户名和密码:
验证登录:
重定向方法:
添加属性:
获取HttpSession对象:
将请求内部派发到指定地址:
1.getRequestDispatcher(path)
2.forward(request, response);
完整参考代码:
分析题意:
没问题,项目先创建上:
再看:
题目一来就给我们表单代码——method = "post"赤果果告诉我们:所要定义的servlet是继承HttpServlet类并重写doPost方法。
public class servlet01 extends HttpServlet {protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
//重写doPost方法}
}
且这份表单会收集数据,交给url路径为"doLogin"的servlet——那我们就要注解配置servlet
@WebServlet("/doLogin")
那么现在的代码就是这样:
@WebServlet("/doLogin")//注解配置servlet路径
public class servlet01 extends HttpServlet {protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
//重写doPost方法}
}
处理POST请求:
那么怎么处理POST请求?我们先根据以往的知识——这首当其冲的,便是设置编码
//1.设置编码 只要是重写doPost方法,第一步一定是设置编码(其实doGet也是)
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
然后呢?接下来就得结合题意了:
获取获取表单中的用户名和密码:
基本方法:
Object request.getParameter(String);
//参数为键 返回为值——故此方法又为:获取请求参数的值
根据表单信息很容易知道:用户名和密码它们的键名
且二者键名的值类型为String ,于是有了两行对应代码:
//2.获取请求参数值String uname = request.getParameter("userName");String pwd = request.getParameter("pwd");
验证登录:
要验证登录:即判断用户名和密码是否正确——如果正确,则balabala;反之,则balabala;
呼之欲出的if-else判断:
if()//如果用户名和密码正确
{}
else//反之
{}
那么if的括号里怎么判断呢?已知我们从表单里获得了用户名和密码的值——类型都是String;还已知正确的用户名为“xx”、密码为“123456”
代码逻辑便是:两个字符串是否相等: "xx"是否等于 uname "123456"是否等于 pwd
if("xx".equals(uname) && "123456".equals(pwd))//判断用户名和密码是否正确,使用String类的成员方法equals
{}
else
{}
接下来,进入执行体;我们先使用伪代码,把能写的代码解决~~~
if("xx".equals(uname) && "123456".equals(pwd))//判断用户名和密码是否正确,使用String类的成员方法equals
{//验证通过,则将用户名添加为HttpSession的一个属性,//再将请求内部派发到home.html;
}
else
{//如果用户名和密码不正确,则将请求重定向到login.html;
}
“添加属性” 这我们在上一节也提到过(详细地)但是没说过——添加为HttpSession的一个属性啊JAVA Web_定义Servlet2_学生登录验证Servlet-CSDN博客;
"请求内部派发"也提到过(这里也得详谈了)。
"重定向"?我们也说过,虽然没归纳具体的方法(这里就得详谈了),但刷了上一道的小伙伴,应该有点印象。看else语句应该比较少,我们先写else:
重定向方法:
sendRedirect()
方法定义在 HttpServletResponse
接口中,具体方法签名如下:
重定向方法:
void sendRedirect(String location) throws IOException
参数 :字符串类型的参数,这个参数是个地址。表示要重定向到的目标 URL。它可以是相对路径或绝对路径
没有返回值。
使用示例:如果说用户登录失败,那么就可以将网址(url)重定向到指定地网站如:login.html
那么此处的代码逻辑也是恰好同理:
//将请求重定向到login.html;
response.sendRedirect("login.html");
//这里可千万记住是:重定向是response的方法(别问作者为什么强调,某些同学不熟容易迷糊)
//好理解,验证获取到的参数值不对,那就直接响应回去到login.html,示意用户重新提交表单
if("xx".equals(uname) && "123456".equals(pwd))//判断用户名和密码是否正确,使用String类的成员方法equals
{//验证通过,则将用户名添加为HttpSession的一个属性,//再将请求内部派发到home.html;
}
else
{//如果用户名和密码不正确,则将请求重定向到login.html;response.sendRedirect("login.html");
}
添加属性:
上一节是将某某属性添加到request的作用域 —— 我们曾拆解“作用域”——理解为一个存储容器,“添加属性”——理解为添加一对键值对。
JAVA Web_定义Servlet2_学生登录验证Servlet-CSDN博客
request.setAttribute(String,Object);//添加属性到request作用域
//参数:前者为新键名,后者为值
那么这里要求: 将用户名添加为HttpSession的一个属性
request.setAttribute("name",uname);
//别急,无论如何,我们添加了用户名属性(新键名为"name",值为uname),至于如何添加到HttpSession,就在下文
这里不再是request的作用域,而是HttpSession:其实照猫画虎,定语变了而已,那么想办法先获得这个HttpSession。
获取HttpSession
对象:
request.getSession()
是 Java Servlet API 中 HttpServletRequest
类的一个常用方法,用于获取与当前请求相关的 HttpSession
对象。
request.getSession()
方法有两种重载形式:这里我们使用第一种
HttpSession request.getSession()
//无参
//如果当前请求已经关联了一个会话,则返回该会话对象。
//如果当前请求没有关联会话,则创建一个新的会话对象,并将其与当前请求关联起来。
//返回值类型为 HttpSession。
这里出现了新的名词“会话”,正是Session的中文。(至于Session的介绍,后面的文章会着重介绍,这里不多说)
知道这个方法会返回我们要的HttpSession对象,就找到了存储新属性的容器~
HttpSession要添加一个属性(键值对),也有个同名成员方法: setAttribute(String,Object);巧了不是?则代码:
request.getSession().setAttribute("name",uname);
//request.getSession()返回值为HttpSession
//要在HttpSession里添加属性,马不停蹄地调用它的setAttribute(String,Object)方法
if("xx".equals(uname) && "123456".equals(pwd))//判断用户名和密码是否正确,使用String类的成员方法equals
{//验证通过,则将用户名添加为HttpSession的一个属性,request.getSession().setAttribute("name",uname);//再将请求内部派发到home.html;
}
else
{//如果用户名和密码不正确,则将请求重定向到login.html;response.sendRedirect("login.html");
}
将请求内部派发到指定地址:
“将请求内部派发到指定地址”
什么意思?好理解,就是这个Servlet处理一定的工作量,接下来的过多的内容得交给下一个Servlet或者html亦或者jsp处理。
而且,注意:“将请求内部派发”,很明显派发到下一个人处理的时候还捎带了这里的数据。
说了这么多,我们请出它的“庐山真面目”:
1.getRequestDispatcher(path)
getRequestDispatcher()
是 Java Servlet API 中 HttpServletRequest
类的一个方法,用于获取一个RequestDispatcher
对象。(你想,方法都叫"getXXX",返回值为XXX也好理解)
RequestDispatcher
对象又实现了Java Servlet API 中的一个接口,即 RequestDispatcher
接口本身。用于在服务器端将请求从一个 Servlet 或 JSP 页面转发到另一个资源,(跟题意吻合check!)或者将另一个资源的内容包含到当前响应中。它是实现请求转发和资源包含的核心机制。
RequestDispatcher getRequestDispatcher(String path)
// 参数path:字符串类型。表示 目标资源的路径 或者 目标资源的 URL
// 返回类型:RequestDispatcher 返回一个 RequestDispatcher 对象,用于后续的请求转发或资源包含操作。 如果路径无效或目标资源不存在,返回 null。
使用示例:
假设我们要实现一份问卷调查收集,第一页(交给servlet01)是处理收集到的用户的姓名和密码;第二页(交给“servlet02”)就处理收集到的用户的爱好和头像、个人简介——很明显,我们转发到第二页问卷的时候的代码:
request.getRequestDispatcher("servlet02");
当然,现在已经内部转发到servlet02了。但是在处理“爱好”、“头像”和“个人简介”也得有对应那个用户的姓名,密码(可不添加)。不然这“爱好”、“头像”和“个人简介”处理的时候,找不到是哪个用户的所填:
2.forward(request, response);
请求转发(Forward)是 Java Servlet API 中 RequestDispatcher
接口(上个方法的返回值实现的同名接口)的一个核心功能
请求转发在服务器端完成,客户端不会感知到目标资源的变更,浏览器地址栏中的 URL 也不会改变。
void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
// 此方法是RequestDispatcher的成员方法,所以调用使用"."
参数
request:ServletRequest 对象,表示当前的请求。
response:ServletResponse 对象,表示当前的响应。
没有返回值。
大家想必也看出来,这两个方法可谓是环环相扣。forward(request,response)是一个成员方法,谁的成员?正是getRequestDispatcher("某个地址/资源地址")的返回值。
所以想要实现请求转发—— 先明确要转发到哪里,再调用forward();(括号里为当前的request和response)
使用场景:
假设我们要实现一份问卷调查收集,第一页(交给servlet01)是处理收集到的用户的姓名和密码;第二页(交给“servlet02”)就处理收集到的用户的爱好和头像、个人简介。
那么在servlet01请求内部派发/请求转发时,代码:
request.getRequestDispatcher("servlet02").forward(request,response);
//当前的request能获得调用forward()的对象,顺便参数里填要转发的映射地址(字符串类型)
//再调用forward,完成请求转发。包含当前请求和响应;可以将请求转发到下一步,同时保留用户已经填写的数据。
那么回看题干:再将请求内部派发到home.html;
request.getRequestDispatcher("home.html").forward(request,response);
// 请求转发在服务器端完成,用户端不会收到新的请求(表单),所以浏览器(客户端)的url不会变
// 说白了请求转发就是流水线上的几个servlet分工处理数据,是服务端的事
if("xx".equals(uname) && "123456".equals(pwd))//判断用户名和密码是否正确,使用String类的成员方法equals
{//验证通过,则将用户名添加为HttpSession的一个属性,request.getSession().setAttribute("name",uname);//再将请求内部派发到home.html;request.getRequestDispatcher("home.html").forward(request,response);
}
else
{//如果用户名和密码不正确,则将请求重定向到login.html;response.sendRedirect("login.html");
}
那么我们综合代码来看:
@WebServlet("/doLogin")
public class servlet01 extends HttpServlet {private static final long serialVersionUID = 1L;protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{//1.设置编码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//2.获取请求参数值String uname = request.getParameter("userName");String pwd = request.getParameter("pwd");//3.判断if("xx".equals(uname) && "123456".equals(pwd)){request.getSession().setAttribute("name", uname);request.getRequestDispatcher("home.html").forward(request, response);}else{response.sendRedirect("login.html");}}
}
运行验证一下:
按理说:它会交给doLogin映射的servlet01;且我输入的用户名和密码正确,最后应该内部派发到home.html(但因为是请求转发,所以url路径还应该是doLogin)
题上并没实现home.html:这是作者简单写的一个打印html,纯纯用来验证:
<h2> 欢迎您,xx </h2>
完整参考代码:
@WebServlet("/doLogin")
public class servlet01 extends HttpServlet {private static final long serialVersionUID = 1L;protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{//1.设置编码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//2.获取请求参数值String uname = request.getParameter("userName");String pwd = request.getParameter("pwd");//3.判断/*验证登录用户提交的用户名是否为xx,密码为123456,如果验证通过,则将用户名添加为HttpSession的一个属性,再将请求内部派发到home.html;(60%)3、如果用户名和密码不正确,则将请求重定向到login.html;(10%)
*/if("xx".equals(uname) && "123456".equals(pwd)){request.getSession().setAttribute("name", uname);request.getRequestDispatcher("home.html").forward(request, response);}else{response.sendRedirect("login.html");}}
}
本章新知识:重定向方法介绍 请求转发方法 获取HttpSession对象并添加属性
今天练习就到这里,如果是对POST请求处理不熟悉,以及代码陌生的同学可以移步这两篇:
JAVA Web_定义Servlet_1 欢迎考生-CSDN博客 - GET请求处理
JAVA Web_定义Servlet2_学生登录验证Servlet-CSDN博客 - POST请求处理