Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
getWrite(); 字符输出流 getOutputStream(); 字节输出流
两者不能同时使用
案例:向客户端输出中文
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置响应类型和字符编码为UTF-8, 这样支持汉字显示
// resp.setContentType("text/html");
// resp.setCharacterEncoding("UTF-8");
//设置客户编码类型
resp.setHeader("Content-Type", "text/html;charset=utf-8");
//不设置编译类型,默认编码发送数据 ISO-8859-1(没有中国二字编码),此时会发生乱码
resp.getWriter().write("hello你好");
}
常见的状态码参照:HTTP状态码详解
设置响应状态码
Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String filename = "Java基础考试题卷.docx";
//下载文件
String path = "C:/Users//Desktop/upload/" + filename;
FileInputStream fis = new FileInputStream(path);
//设置请求头,文件名需要UTF-8编码
filename = URLEncoder.encode(filename, "UTF-8");
resp.setHeader("Content-disposition", "attachment;filename=" + filename);
byte[] bs = new byte[1024];
ServletOutputStream sos = resp.getOutputStream();
int len = 0;
while((len = fis.read(bs)) != -1){
sos.write(bs, 0, len);
}
fis.close();
}
实际开发直接调包
输出随机图片(CAPTCHA图像):Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的测试)
相关主要类(JDK 查看API)
Sevlet
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
int WIDTH=120;
int HEIGHT=30;
//创建画布
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//创建画笔
Graphics g = image.getGraphics();
//设置画笔颜色
g.setColor(Color.YELLOW);
//画背景
g.fillRect(0, 0, WIDTH, HEIGHT);
//设置干扰线颜色
g.setColor(Color.BLUE);
//加干扰线
for(int i=0;i<6;i++){
int xStart = new Random().nextInt(WIDTH);
int yStart = new Random().nextInt(HEIGHT);
int xEnd = new Random().nextInt(WIDTH);
int yEnd = new Random().nextInt(HEIGHT);
g.drawLine(xStart, yStart, xEnd, yEnd);
}
int x = 5;
//画随机数
for(int i = 0; i< 4;i++){
g.drawString(new Random().nextInt(9) + "", x+i*30, 20);
}
//输出图片 设置响应格式
resp.setContentType("image/jpeg");
ImageIO.write(image, "JPEG",resp.getOutputStream());
}
html
效果
如何关联静态html和class 1.Html中的src写 /项目名/对应类的@WebServlet注解地址 2.对应类只需要加上路由注解 3.访问的时候为/项目名/html名字.html
ValidateCode(width,height,码数,干扰数)
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
重定向特点:地址栏会变,并发送2次请求,增加服务器负担
实现方式
response.sendRedirect(request.getContextPath()+”/转发注解”)
实现原理: 302/307状态码和location头即可实现重定向
转发特点:地址栏不会变,客户端发送一次请求,状态码依旧200
request.getRequestDispatcher(“/转发注解”).forward(request,response)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws ServletException, IOException {
//浏览器刷新时就不会有缓存
response.addHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
ValidateCode code = new ValidateCode(WIDTH, HEIGHT, 4, 6);
code.write(response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
//response.setHeader("Refresh", "1");//每隔一秒刷新一次
response.setHeader("Refresh", "5;URL=index.html");//3秒后转到另一页面
response.getWriter().write("注册成功!3秒后会自动跳转,苦没有中转点击<a href='index.html'>这里</a>");
}
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
Map查询效率非常高,通常用上图方法来遍历Map(entrySet返回Entry,然后通过entry查询
目标:掌握通过getParameter和getParameterValues获取请求参数 掌握POST和GET请求解决乱码的方案 掌握表单提交通过都用POST方法
<form action="/项目名/注解内的地址" method="post">
用户名:<input type="text" name="username"><br>
密---码:<input type="password" name="password"><br>
性---别:<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女<br>
爱---好:<input type="checkbox" name="hobby" value="写代码">写代码
<input type="checkbox" name="hobby" value="看书">看书
<input type="checkbox" name="hobby" value="听课">听课<br>
备---注:<textarea rows="5" cols="20" name="remark"></textarea><br>
<input type="submit" value="提交">
</form>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收表单请求参数
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String gender = request.getParameter("gender");
String remark = request.getParameter("remark");
String[] hobby = request.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(gender);
System.out.println(remark);
System.out.println(Arrays.toString(hobby));
}
Model
Servlet
public class Test extends HttpServlet{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
//post请求时,中文会乱码,解决方法setCharacterEncoding,只针对post请求有效
request.setCharacterEncoding("UTF-8");
//创建用户对象
User user = new User();
//获取请求参数
/**
* key value
* username {"shunxu"};
* password {"123"};
* hobby {"study","reading"}
*/
Map<String, String[]> map = request.getParameterMap();
try {
for(Entry<String, String[]> entry : map.entrySet()){
String pname = entry.getKey();
//通过name创建对象
if(pname.equals("username")){
user.setUsername(entry.getValue()[0]);
}else if(pname.equals("hobby")){
user.setHobby(entry.getValue());
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(user);
}
}
导入
如果不知道如何选择版本,比较靠谱的方式是去Maven Repository搜索包名,查看最多人用的版本
调包使用
BeanUtils自动将request.getParameterMap()中获取到的Map装载入user中。
请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。 request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。 request对象同时也是一个域对象(context对象),开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
重定向机制的运作流程
HttpServeltResponse的sendRedirect(String location)用于重定向
@WebServlet("/test")
public class Test extends httpServlet{
private static final long serialVersionUID =1L;
protected void doGet(HttpServletRequest request,HttpServeltResponse response)
throws Exception{
String cp = request.getContextPath();
System.out.println(cp); //打印上下文路径
response.sendRedirect(cp+"/login.jsp"); //跳转到jsp页面,需要加上contextPath
}
域对象:session,request,page等(详情关注后续章节) 域:区间、范围
转发存放在Request中的变量不会失效
顾名思义先翻译:
假定第一次请求的为servlet1,处理转发的为servlet2
include()方法将请求转发给servlet2,servle2对该请求做出了的响应并入到原来的servlet1响应对象中,原来的servlet1还可以继续输出响应信息(servlet1和servlet2按顺序依次响应数据,就像是一个页面一样)。
forward方法将请求转发给其他的servlet2,servlet2负责对请求做出响应,而原先的servlet1的执行则终止(servlet1无法响应任何数据)。
sendRedict()在浏览器请求servlet1之后,重新告诉浏览器将请求重新定位到servlet。
具体结果读者自行尝试