题目
假定:本地服务器(127.0.0.1)上有一名为jspExam的Web项目,现按要求定义一Servlet,实现以下功能:
1)Servlet的类名自定义,假定可以用以下url访问该Servlet,
http://127.0.0.1:8080/jspExam/exam?username=xxx&usernumber=+++
请用注解方式配置该Servlet的url。其中“xxx”代表考生姓名,“+++”代表考生考号。
2)该Servlet处理get请求方式;
3)该Servlet返回HTML格式的内容;
4)访问该Servlet将根据参数username和usernumber输出不同的内容:“欢迎xxx,你的考号是+++”,比如:username=张三&usernumber=123456
将输出:欢迎张三,你的考号是123456
注释:
利用String对象手动实现编码转换:
new String(name.getBytes("IS0-8859-1"),"utf-8")
前文链接:如何在Eclipse新建一个Web项目-CSDN博客
JAVAWeb_Servlet:前置准备与理论简易介绍-CSDN博客
因为这是我们第一次真正意义上,编写Servlet的代码。所以接下来想要实现这个小项目,我们会先顺着题目来一步一步来:
1. 创建项目
根据题意,“本地服务器”就是我们自己的计算机,OK,已经准备好了。接下来,按照题上说:“名为jspExam的Web项目”。—— 意味着 我们的项目名称为jspExam
2. 定义Servlet
现在我们需要定义一个Servlet,要求实现以上4个功能:
2.1 Servlet类名 与 注解方式配置Servlet的URL
既然该Servlet的类名自定义,那作者就不客气了:就叫……ExamServlet
也是到这儿发现一个技巧:就是直接创建servlet时也可以顺便把包建了(扶额邪魅一笑)“Java package”包名这儿——作者就直接上网名了。
创建完后:
(作者为了更加详细地编写servlet,把事先的代码都删掉)
servlet类名自定义ok后,接下来我们需要使用注解方式配置该 Servlet 的 URL 映射:
还记得注解方式配置Servlet的url的语法吗:
@WebServlet("...")
// ...为绝对路径。以 / 开头,表示从项目的根路径开始。
项目名为题意上jspExam,而这个servlet的url映射路径我们则需要根据题意,我们注意观察 :
看清了看清了,项目后的路径“/exam”,那么则这个servlet的映射Url正是这个:
于是注解代码:(不要加分号哈)
@WebServlet("/exam")
有同学会说:“欸作者,第一个功能还有最后一截信息,就不管了吗?”
意味深长地摇摇头:非也非也。接下来我们会揭晓这部分是何物?
2.2 处理GET请求
根据我们的前置知识:我们简单介绍了get请求和post请求,只是留下了眼缘。这里题上明确要求我们处理get请求:那么我们可以将代码开头了:(不熟悉开头的同学,可先移步这篇文章JAVAWeb_Servlet:前置准备与理论简易介绍-CSDN博客
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{//将我们的servlet继承HttpServlet,我们就可以重写HttpServlet它的doGet方法
}
接下里,重写doGet方法:不管什么逻辑,先搭框架
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{//将我们的servlet继承HttpServlet,我们就可以重写HttpServlet它的doGet方法protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{}
}
我知道大家在写代码时,会出现警告报错:
这是因为没有导入相应的程序包:还记得在前置知识里说的快捷键吗(勾唇一笑),Ctrl+Shift+O
解决了。
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{//那这里应该怎么处理呢?}
}
先来解决刚刚的遗留问题:
“?username=xxx&usernumber=+++”是什么?
2.2.1 查询字符串:
整个http://127.0.0.1:8080/jspExam/exam?username=xxx&usernumber=+++是一个 HTTP GET 请求的 URL。
而?username=xxx&usernumber=+++是查询字符串(Query String)。用于向服务器传递额外的参数——这里,传入了两个参数,第一个参数名字是username,它的值为xxx;第二个参数名为usernumber,它的值为+++。两个参数以&分隔。
//查询字符串的语法
?key1=value1&key2=value2&key3=value3
//通俗来说,在servlet的url映射路径后,以?开头后面跟着一系列键值对,键值对之间用 & 分隔的部分
虽说查询字符串对于其他请求可用于传递额外的参数,但对于GET请求而言,它最经典的传参就是依靠查询字符串,我们往往将查询字符串的传入的参数作为GET请求要处理的参数。有同学要问了,为什么要传参呢?
用户在请求时传递参数的主要原因是向服务器提供必要的信息,以便服务器能够根据这些信息生成相应的响应。也就是提供用户所需要的服务。
2.2.2 处理内容
现在来正式处理GET请求:根据题意,我们站在服务端的角度,面对客户端传来的GET请求包含了ta的名字和考号,ta所需要的响应——正是针对用户相应的名字和考号按格式输出信息
我们在前导篇说过,用户的请求会在doGet方法里打包成一个类的对象:httpServletRequest request。
要输出这样的信息,我们得从获得的请求里,拿到username和usernumber这两个参数的值。
2.2.3 获取请求里的参数
HttpServletRequest里有个成员方法:getParameter("...")可以帮我们获取请求里的参数,不仅仅是GET请求。
// 方法概述
String getParameter(String name)
// 参数name:String类型,指定要获取的参数名称。
//返回值 :String类型,表示请求中具有指定名称的参数值。如果请求中没有该名称的参数,则返回null。
我们举个例子:假设客户端发来一个请求,客户端那边的提交的username(用户名)这个参数的值为Zhao Qiansun。我们在编写servlet时,需要获得客户端的用户名。
String usrname = request.getParameter("username");
// 这句代码是写在我们的servlet里,我们定义一个usrname去接收request里参数名为username的值
if(usrname = null)
{//这里表明我们表示客户端没传它的username 或者 请求里并没有名为username的参数//所以getParameter("")后返回null
}
else
{//处理参数
}
再来看需求,我们就明白这个Get请求里,客户端传来了两个参数的值:
//一个参数的值是username=张三
//另一个是usernumber=123456
按照后续打印要求,我们很明显需要这两个参数,于是我们可以先调用getParameter("")来获取这两个参数。(题上并没有说null时怎么处理,那么我们也就忽略)
String name = request.getParameter("username");//不出意外,name="张三"
String number = request.getParameter("usernumber");//不出意外,number="123456"
写进整体的代码:
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{String name = request.getParameter("username");String number = request.getParameter("usernumber");}
}
2.2.4 响应时输出要求内容
Servlet里,要在网页输出内容——也有个方法。很明显,这是响应的内容;所以调用的方法也是response的成员函数。
PrintWriter getWriter()
//返回一个PrintWriter对象,该对象可用于向客户端发送字符文本响应。
//无参调用
//返回PrintWriter类型,表示用于向客户端发送字符文本响应的输出流。
//异常IOException:如果发生输入/输出错误,例如在获取输出流时出现异常。
关于输出流:按照作者奇思妙想的理解,输出流就是建立一条管道:管道里从内存到目的地(此处是我们的网页)管道里输出着一个一个要求我们打印的字符/字节。——于是就此分为 字符流/字节流。
那具体怎么用呢? 要输出“欢迎xxx,你的考号是+++”.其实就是 : 1. 建立一条输出管道(获取响应的输出流) 2. 往输出流放入我们要输出的字符
怎么放入呢? 其实在JAVA里,和我们刚开始学的打印方法一样的名字:println/write
甚至用法都是一样的。
对比
println()
:在写入内容后自动添加行分隔符,适合输出多行文本。
write()
:不会自动添加行分隔符,适合输出连续的文本内容。
这里大家随意选择:
所以这段“输出要求内容”的代码:
PrintWriter out = response.getWrite();//1. 获取响应的输出流
out.println("欢迎"+name+",你的考号是"+number);// 2. 使用打印方法,放入我们要输出的字符串
结合前面的代码:
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{String name = request.getParameter("username");String number = request.getParameter("usernumber");//到这儿,成功获取所需参数//输出要求内容PrintWriter out = response.getWriter();out.println("欢迎"+name+",你的考号是"+number);}
}
作者已经迫不及待运行这个servlet了:
在自动跳转的浏览器的URL里记得传参(查询字符串)——是的,自己又当写servlet的服务端又当传参的客户端(邪魅一笑)
结果:
好家伙,乱码了。
2.2.5 响应乱码解决
中文乱码问题,就是这编码方式不认识咱们汉字,编不了咱们汉字。没事儿,我们就先设置编码。这编码不行,咱们就换个编码——如:UTF-8
既然是响应乱码……其实响应为我们提供了要设置编码方式的方法:setContentType();
我们一般就是解决中文乱码,那么就加上这句就没问题了:
response.setContentType("text/html;charset=UTF-8");
//charset - 字符集 意味着使用utf-8编码的字符集
//那前半截是什么意思?
//text/html 的功能: 告诉客户端:响应的内容是一个HTML文档。 浏览器应该按照HTML的规则来解析和渲染这些内容。
这句代码可谓一箭双雕:既设置了响应的编码方式和响应的内容类型(html格式)
顺便完成了刚刚忽略的第3)点(再次邪魅一笑)
所以完整的代码:
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{//上来就设置响应的编码和内容类型response.setContentType("text/html;charset=UTF-8");String name = request.getParameter("username");String number = request.getParameter("usernumber");//到这儿,成功获取所需参数//输出要求内容PrintWriter out = response.getWriter();out.println("欢迎"+name+",你的考号是"+number);}
}
客户端(网页输出):
完整参考代码:
@WebServlet("/exam")
public class ExamServlet extends HttpServlet
{protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{request.setCharacterEncoding("UTF-8");//这句话理论说,在处理GET请求不必加(甚至多余)
//但是,如果处理了响应编码后输出仍乱码的话,很可能是在对请求体解码时错误。加上可能多余但绝不会出错response.setContentType("text/html;charset=UTF-8");String name = request.getParameter("username");String number = request.getParameter("usernumber");//到这儿,成功获取所需参数//输出要求内容PrintWriter out = response.getWriter();out.println("欢迎"+name+",你的考号是"+number);}
}
如果有同学好奇作者怎么解释servlet的运行,以及servlet代码入门:不妨继续移步:JAVAWeb_Servlet:前置准备与理论简易介绍-CSDN博客
如果这篇文章的题目已经通关,我们接下来则继续处理另一种常见请求:POST请求。敬请期待……(抱拳)