web服务器收到客户端的HTTP请求,会针对每一次请求分别创建一个用于代表请求的request对象和代表响应的response对象。
1.要得到客户机提交过来的数据,只需要找request对象就行了。
2、要向客户机输出数据,只需要找response对象就行了。
一、response对象
1.1向客户端发送数据,以字节为单位(一定要先设置编码方式,再输出)
-
String
data =
"你好,中国1";
-
OutputStream
out = response.getOutputStream();
-
out.write(
data.getBytes());
//查找本机默认编码进行编码
-
String
data =
"你好,中国2";
-
OutputStream
out = response.getOutputStream();
-
out.write(
data.getBytes(
"UTF-8"));
//以UTF-8进行编码
-
//告诉浏览器编码方式
-
response.setHeader(
"Content-Type",
"text/html;charset=UTF-8" );
-
String
data =
"你好,中国3";
-
OutputStream
out = response.getOutputStream();
-
out.write(
"<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>".getBytes());
通过meta标签模拟请求头
-
out.write(
data.getBytes(
"UTF-8"));
//以UTF-8进行编码
-
String
data =
"你好,中国4";
-
OutputStream
out = response.getOutputStream();
-
response.setContentType(
"text/html;charset=UTF-8");
-
out.write(
data.getBytes(
"UTF-8"));
//以UTF-8进行编码
response.setContentType("text/html;charset=UTF-8");
等价于下面两句代码的效果:
response.setCharacterEncoding("UTF-8");//更改服务器发送数据的默认编码
response.setHeader("Content-Type","text/html;charset=UTF-8");//还要通知客户端解码方式
-
int x=
97;
-
OutputStream
out = response.getOutputStream();
-
out.write((x+
"").getBytes());
向客户端发送数字
1.2 以字符为单位向客户端发送数据
String data = "你是谁?";
response.setCharacterEncoding("UTF-8"); //设置编码为UTF-8
response.setHeader("Content-Type", "text/html;charset=UTF-8");//告诉客户端编码方式
// 第二种方法:相当于以上两句代码
//response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();//默认编码是iso-8859-1 创建该对象前必须设置好编码方式
writer.write(data);
System.out.println(response.getCharacterEncoding());
1.3 让客户端以下载方式打开文件,解决中文文件名乱码问题(URLEncoder.encode(name, "UTF-8"))
-
//得到文件的真实路径
-
String realPath = getServletContext().getRealPath(
"/files/漂亮美眉.jpg");
-
//获取文件名
-
String name = realPath.substring(realPath.lastIndexOf(
"\\"));
-
-
//设置响应头,通知客户端以下载的方式打开文件
-
response.setHeader(
"Content-Disposition",
"attachment;filename="+URLEncoder.encode(name,
"UTF-8"));
-
-
//构建输入流
-
InputStream
in =
new FileInputStream(realPath);
-
-
//输出到客户端的流
-
OutputStream
out = response.getOutputStream();
-
int len =
-1;
-
byte buf[] =
new
byte[
1024];
-
while((len=
in.read(buf))!=
-1)
-
{
-
out.write(buf,
0, len);
-
}
-
-
in.close();
1.4 输出随机数字生成验证码图片
-
//设置不要缓存(3种方式,建议三种都设置,防止浏览器不支持)
-
response.addHeader(
"Pragma",
"no-cache");
-
response.setHeader(
"Cache-Control",
"no-cache");
-
response.setHeader(
"Expires",
"0");
-
-
//1.内存图像 BufferedImage
-
BufferedImage image =
new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
-
-
//2.创建画笔
-
Graphics g = image.getGraphics();
-
-
//2.1画边框
-
g.setColor(Color.GRAY);
//设置边框颜色
-
g.drawRect(
0,
0, WIDTH, HEIGHT);
//画矩形边框
-
//2.2填充边框
-
g.fillRect(
1,
1, WIDTH-
1, HEIGHT-
1);
-
-
//2.3输出验证随机数字4个
-
Random r =
new Random();
-
g.setColor(Color.BLUE);
-
int x =
5;
-
for(
int i=
0;i<
4;i++)
-
{
-
-
g.setFont(
new Font(
"宋体",Font.BOLD,
20));
-
g.drawString(r.nextInt(
10)+
"", x,
20);
-
x+=
30;
-
}
-
-
//2.4画干扰线
-
g.setColor(Color.YELLOW);
-
for(
int i =
0;i<
9;i++)
-
{
-
-
g.drawLine(r.nextInt(WIDTH),r.nextInt(HEIGHT), r.nextInt(WIDTH), r.nextInt(HEIGHT));
-
}
-
-
//3 利用response输出流输出image
-
ImageIO.write(image,
"jpeg",response.getOutputStream());
-
//response.setHeader(
"Expires", (System.currentTimeMillis()+
24*
3600*
10*
1000)+
"");//缓存
10天
-
response.setDateHeader(
"Expires",System.currentTimeMillis()+
10*
24*
1000*
60*
60);
1.5 控制客户端刷新时间
-
//response.setHeader("Refresh", "5;URL=/day05/default.html");//5秒后跳转,url是跳转的链接
-
response.getOutputStream().write("
<meta http-equiv=\"Refresh\" content=\"3;URL=/day05/login.html\">".getBytes());
1.6 控制客户端缓存时间
-
//response.setHeader(
"Expires", (System.currentTimeMillis()+
24*
3600*
10*
1000)+
"");//缓存
10天
-
response.setDateHeader(
"Expires",System.currentTimeMillis()+
10*
24*
1000*
60*
60);
1.7 用response实现请求重定向
特点:地址栏会变,发送两次请求,增加服务器负担。
实现方式:response.sendRedirect()
实现原理:302状态码和location头即可实现重定向
-
//response.sendRedirect("/day05/servlet/ResponseDemo5");//绝对路径
-
注意
// response.sendRedirect("/servlet/ResponseDemo5");//相对路径这里用是错误的,因为重定向是由客户端发起的
-
response.setStatus(
307);
//302 或者 307都可
-
response.setHeader(
"location",
"http://localhost:8080/day05/servlet/ResponseDemo1");
1.8 小细节
-
String s1 =
"abc";
-
String s2 =
"def";
-
response.getOutputStream().write(s1.getBytes());
-
//response.getWriter().write(s2);
-
//注:getOutputStream和getWriter这两个方法互相排斥,
-
//调用了其中的任何一个方法后,就不能再调用另一方法,会抛异常。
-
//java.lang.IllegalStateException:
-
//getOutputStream() has already been called for this response
二、request(HttpServletRequest)对象
2.1.get方法
-
String locale = request.getLocalName();
//传输协议
-
String url = request.getRequestURL().toString();
//请求的地址
-
String uri = request.getRequestURI();
//没有主机名的地址
-
String protocol = request.getProtocol();
//获取协议
-
String add = request.getRemoteAddr();
//客户端IP
-
String host = request.getRemoteHost();
//客户端主机名
-
String port = request.getRemotePort()+
"";
//客户端端口号
-
String method = request.getMethod();
//客户端的请求方式
-
String localAddr = request.getLocalAddr();
//获取服务器地址
-
String username = request.getParameter(
"username");
//地址后面?请求的参数
-
String serverPort = request.getServerPort()+
"";
//服务器端口号
-
String serverName = request.getServerName();
//服务器名
2.2 获取客户端请求头
-
response.setContentType(
"text/html;charset=UTF-8");
-
-
PrintWriter
out = response.getWriter();
-
//获取单个请求头的值
-
out.write(request.getHeader(
"Accept-Language")+
"<br/>");
-
//获取单个请求头多个值
-
Enumeration headers = request.getHeaders(
"user-agent");
-
while(headers.hasMoreElements())
-
{
-
out.println(headers.nextElement()+
"<hr/>");
-
}
-
-
//获取所有的请求头名
-
Enumeration names = request.getHeaderNames();
-
while(names.hasMoreElements())
-
{
//根据请求头名得到对应的值
-
String name = (String)names.nextElement();
-
out.println(name+
"="+request.getHeader(name)+
"<br/>");
-
}
2.3获取请求参数
String usernameValue = request.getParameter("username");//参数不存在为null
-
String names[] = request.getParameterValues(
"username");
-
for(
String name:names)
-
{
-
System.out.println(name);
得到某个请求参数的所有值
-
-
}
-
//获取所有的请求参数名
-
-
Enumeration names = request.getParameterNames();
-
while(names.hasMoreElements())
-
{
//根据参数名得到值
-
String name = (
String)names.nextElement();
-
System.out.println(name+
"------->"+request.getParameter(name));
-
}
2.4 封装到bean
-
public
class
Student {
-
private String[] username;
-
private String password;
-
-
public String[] getUsername() {
-
return username;
-
}
-
public void setUsername(String[] username) {
-
this.username = username;
-
}
-
public String getPassword() {
-
return password;
-
}
-
public void setPassword(String password) {
-
this.password = password;
-
}
-
-
-
}
-
-
//利用BeanUtils和 getParameterMap()将对象封装到bean
-
private void test5(HttpServletRequest request) {
-
// TODO Auto-generated method stub
-
Map map = request.getParameterMap();
-
Student s =
new Student();
-
try {
-
BeanUtils.populate(s, map);
-
}
catch (IllegalAccessException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
catch (InvocationTargetException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
String[] names = s.getUsername();
-
System.
out.println(names[
0]);
//aa
-
System.
out.println(names[
1]);
//bb
-
System.
out.println(s.getPassword());
//123
-
}
//从客户端传过来的值username两个(假如是aa和bb) 和一个password值(假如是123)
2.5 得到请求正文
-
//获取请求正文
-
InputStream in = request.getInputStream();
-
byte[] buf =
new
byte[
1024];
-
int
len =
-1;
-
while((
len=in.read(buf))!=
-1)
-
{
-
System.out.
println(
new String(buf,
0,
len));
-
}
2.6解决请求参数的中文乱码
get方式:先按照原编码得到原始字节码,然后再重新编码。如:name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
post方式:客户端是什么编码,发送的请求数据就是什么编码,根据客户端的编码,告知服务器编码方式。
如:request.setCharacterEncoding("UTF-8");// 只适合POST请求方式
2.7请求转发 forward
RequestDispatcher rd = request.getRequestDispatcher("path");//得到转发器,path可以是相对路径或者绝对路径(因为是服务器发起的)
rd.forward(request, response);
2.8 包含include
RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo9");
rd.include(request, response);
三 、路径的写法:
a、绝对路径写法:ServeltContext都必须用绝对路径。“/”开始 (如ServletContext.getRequestDispatcher("path") path必须是绝对路径)
b、相对路径:其他情况都可以使用相对路径,也可以使用绝对路径
c、在使用绝对路径时,要不要加"/"或者是项目名:如果是服务器调用的,不用加项目名,用“/”就可以代表了当前应用根目录
如果是客户端调用的,必须加上项目名
1、转发:request.getRequestDispather(String url)
绝对路径:url /servlet/ServletDemo
2、重定向:response.sendRedirect(String url)
绝对路径:url /day05/servlet/ServletDemo
3、超链接:<a href="url"/>
绝对路径:url /day05/servlet/ServletDemo
4、类加载文件的路径
web应用中只能用相对路径,相对于classes目录的
5、<fomr action="url"/>
绝对路径:/day05/servlet/ServletDemo
6、页面分帧(frame)
绝对路径:/day05/servlet/ServletDemo
7、ServletContext.getRealPath(url)
绝对路径:url /servlet/ServletDemo
URLEncoder.encode("name", "UTF-8")//解决文件下载名中文乱码