2023.3.1学习日志

文章详细介绍了JavaServlet中的Response和Request对象,包括HttpServletResponse和HttpServletRequest的用途、常用API及实战示例,如设置响应状态码、响应头、字符编码,以及获取请求路径、请求头、请求参数等。同时,提到了JSP技术的特点,如跨平台、业务代码分离、组件重用等,并概述了JSP的工作原理。
摘要由CSDN通过智能技术生成

一.request和response

Response简介

定义辅助 servlet 将响应发送到客户端的对象。servlet 容器创建 ServletResponse 对象,并将它作为参数传递给 servlet 的 service 方法。 要发送 MIME 正文响应中的二进制数据,请使用 #getOutputStream 返回的 ServletOutputStream。要发送字符数据,请使用 #getWriter 返回的 PrintWriter 对象。要混合二进制数据和文本数据,例如要创建 multipart 响应,请使用 ServletOutputStream 并手动管理字符部分。 可使用 #setCharacterEncoding 和 #setContentType 显式指定 MIME 正文响应的 charset,或使用 #setLocale 方法隐式指定它。显式指定优先于隐式指定。如果未指定 charset,则将使用 ISO-8859-1。setCharacterEncoding、setContentType 或 setLocale 方法必须在调用 getWriter 之前,并且必须在提交采用要使用的字符编码的响应之前调用。

7.2 HttpServletResponse介绍

扩展 ServletResponse 接口以提供特定于 HTTP 的发送响应功能。例如,该接口拥有访问 HTTP 头和 cookie 的方法。 客户端向服务器发起的都是HTTP协议操作,所以我们大部分使用HttpServletResponse对象作为直接操作对象!

7.3 HttpServletResponse 常用API介绍

方法名称作用setStatus(int code)设置响应状态码setHeader(name,value)设置响应信息头setCharacterEncoding(String);设置编码格式setContentType(String)设置返回数据mimetypegetWriter()获取字符输出流getOutputStream()获取字节输出流

7.4 设置返回字符编码格式

方案1

response.setCharacterEncoding()

设置tomcat编码格式

<html meta charset=UTF-8 ><body>编写返回的文本内容</body>

设置浏览器解析文本内容格式

可以解决返回字符串乱码问题,但是需要将返回的字符串封装到html代码中.操作繁琐!

方案2

response.setCharacterEncoding()

response.setHeader("Content-type","text/html;charset=UTF-8")

方案按相对简单,通过设置响应头告知浏览器解析字符串的编码格式!

方案3

response.setContentType("text/html;charset=UTF-8")

利用setContentTyoe这种综合性的写法解决问题!此方法也是开发中常用的方法!方便!

7.5 Response练习

用户下载服务器图片

public class DownLoadServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

/**

* 别人访问我 我给你一张图片

*

* 1.获取图片的输入流

* 2.response的字节输出流

*/

//1.获取图片或者文件的输入流

//想要或某个文件 你必须知道绝对路径

//手段: 项目中的相对路径 去获取绝对路径

// /吃鸡.jpg

// /WEB-INF/classes/吃鸡.jpg

// /WEB-INF/classes/com/itqf/servlet/吃鸡.jpg

//ServletContext getRealPath 相对路径转成绝对路径

String path = getServletContext().getRealPath("/吃鸡.jpg");

System.out.println(path);

//文件输入流

FileInputStream stream = new FileInputStream(path);

//xx/xx/x/x/x/x/x/x/吃鸡.jpg

//获取文件的名字 /

//File.separator == /

String filename = path.substring(path.lastIndexOf(File.separator)+1);

//IE

// filename = URLEncoder.encode(filename,"UTF-8");

//其他

filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");

//设置响应头

//content-disposition", "attachment;filename="+filename

//下载用的 attachment下载: filename下载文件的名字

response.setHeader("content-disposition", "attachment;filename="+filename);

//根据文件名字的后缀名获取类型

String mimetype = getServletContext().getMimeType(filename);

response.setContentType(mimetype); //下载文件的类型

ServletOutputStream outputStream = response.getOutputStream();

byte [] buffer = new byte [8*1024];

int len = 0;

while((len=stream.read(buffer)) != -1){

outputStream.write(buffer, 0, len);

}

stream.close();

}

}

页面中添加验证码

项目中添加第三方jar包!validatecode.jar

创建返回验证码的servlet!

public class CodeServlet extends HttpServlet {

/**

* The doGet method of the servlet. <br>

* This method is called when a form has its tag value method equals to get

* @param request the request send by the client to the server

* @param response the response send by the server to the client

* @throws ServletException if an error occurred

* @throws IOException if an error occurred

*/

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//1.设置生成规则

/**

* width:验证码的宽度 px 像素

* height: px

* codeCount:生成验证码有几个数

* lineCount:有几根线

*/

ValidateCode code = new ValidateCode(200, 50, 6, 20);

//2.获取生成的验证码的字符串值

System.out.println(code.getCode()); //获取正确值

//3.响应写回验证图片

code.write(response.getOutputStream());

}

}

页面中使用当前servlet

<!DOCTYPE html>

<html>

<head>

<title>login.html</title>

<meta name="keywords" content="keyword1,keyword2,keyword3">

<meta name="description" content="this is my page">

<meta name="content-type" content="text/html; charset=UTF-8">

<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

</head>

<body>

<form action="/Day11_Response1/servlet/LoginServlet" method="post">

<input type="text" name="username" placeholder="请输入账号!" />

<input type="submit" value="登录"/>

</form>

<img src="/Day11_Response1/servlet/CodeServlet" οnclick="changeCodes()" alt="验证码" title="验证码"/>

<a href="javascript:changeCodes()" >看不清?</a>

<script type="text/javascript">

function changeCodes(){

var img= document.getElementsByTagName("img")[0];

img.src = "/Day11_Response1/servlet/CodeServlet?r="+Math.random();

}

</script>

</body>

</html>

####第八章 Request讲解

8.1 ServletRequst介绍

定义将客户端请求信息提供给某个 servlet 的对象。servlet 容器创建 ServletRequest 对象,并将该对象作为参数传递给该 servlet 的 service 方法。

8.2 HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

小结: 同响应相同,客户端请求协议都是基于HTTP所以我们选用HttpServletRequest来操作用户发送过来的请求的数据!

8.3 HttpServletRequest常用API

//获取请求路径相关参数
getRequestURL方法返回客户端发出请求时的完整URL。getRequestURI方法返回请求行中的资源名部分。getQueryString方法返回请求行中的参数部分。getRemoteAddr方法返回发出请求的客户机的IP地址getRemoteHost方法返回发出请求的客户机的完整主机名getRemotePort方法返回客户机所使用的网络端口号getLocalAddr方法返回WEB服务器的IP地址。getLocalName方法返回WEB服务器的主机名getMethod得到客户机请求方式//获取请求头信息
getHead(name)方法getHeaders(Stringname)方法getHeaderNames方法//获取请求正文参数
getParameter(name)方法getParameterValues(Stringname)方法getParameterNames方法getParameterMap方法//做框架用,非常实用
getInputStream

8.4 获取请求数据练习

//1.测试获取请求行数据的方法和请求头的方法
//1.获取请求行的方法
//获取请求方式
Stringmethod=request.getMethod();//获取请求的url 
Stringurl=request.getRequestURL()+"";//获取uri 
Stringuri=request.getRequestURI();//获取请求的参数  get
Stringquery=request.getQueryString();//获取请求人的id 
Stringip=request.getRemoteAddr();//获取请求的主机名
Stringhost=request.getRemoteHost();System.out.println(method+" url:"+url+" uri:"+uri+" query:"+query+" ip:"+ip+" host:"+host);//获取请求信息
//全部输出  
//post fix
Stringheader=request.getHeader("user-agent");if(header.contains("firefox")){}//获取所有请求的names
Enumeration<String>headerNames=request.getHeaderNames();while(headerNames.hasMoreElements()){Stringname=(String)headerNames.nextElement();//根据name获取keys
Enumeration<String>headers=request.getHeaders(name);while(headers.hasMoreElements()){Stringkey=(String)headers.nextElement();System.out.println(name+"--->"+key);}}

8.5 封装请求参数

将数据封装到实体类上

创建一个对应的实体类!

实体类要变量命名和变量类型都有相应的要求,要求变量名跟提交参数的key相同,变量跟参数类型形同!

publicclassJavaBean{privateStringusername;privateStringpassword;privateStringsex;privateString[]hobby;//getter/setter 
}

原生方式进行解析

//表单的name值和value值
//key  name值  value  values值
Map<String,String[]>parameterMap=request.getParameterMap();JavaBeanbean=newJavaBean();Set<Entry<String,String[]>>entrySet=parameterMap.entrySet();for(Entry<String,String[]>entry:entrySet){//entry map中的一条
//username password sex
Stringkey=entry.getKey();String[]value=entry.getValue();try{PropertyDescriptordescriptor=newPropertyDescriptor(key,JavaBean.class);Methodset=descriptor.getWriteMethod();/**
                 * 参数:哪个对象的set方法
                 * password username sex
                 */if(value.length==1){set.invoke(bean,value[0]);}else{set.invoke(bean,(Object)value);}}catch(IntrospectionExceptione){// TODO Auto-generated catch block
e.printStackTrace();}catch(IllegalAccessExceptione){// TODO Auto-generated catch block
e.printStackTrace();}catch(IllegalArgumentExceptione){// TODO Auto-generated catch block
e.printStackTrace();}catch(InvocationTargetExceptione){// TODO Auto-generated catch block
e.printStackTrace();}}

使用Apache BeanUtils进行快速映射

1.导入beanutils对应jar包!

2.映射

BeanUtils.populate(bean2,request.getParameterMap());System.out.println(bean2);

8.6 Servlet如何处理HTTP协议

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的HttpServletRequest对象、和代表响应的HttpServletResponse对象。
HttpServletRequest和HttpServletResponse对象即然代表请求和响应,那我们要获取客户端提交过来的数据,只需要找HttpServletRequest对象就行了。要向客户端输出数据,只需要找HttpServletResponse对象就行了

8.6.1 HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息
获得客户端信息
  getRequestURL方法返回客户端发出请求时的完整URL。
  getRequestURI方法返回请求行中的资源名部分。
  getQueryString 方法返回请求行中的参数部分。
  getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
  getRemoteAddr方法返回发出请求的客户机的IP地址。
  getRemoteHost方法返回发出请求的客户机的完整主机名。
  getRemotePort方法返回客户机所使用的网络端口号。
  getLocalAddr方法返回WEB服务器的IP地址。
  getLocalName方法返回WEB服务器的主机名。
获得客户端请求头
  getHeader(string name)方法:获取指定名称的String值
  getHeaders(String name)方法:获取指定名称的Enumeration值
  getHeaderNames()方法:获取所有的请求消息头的名称
获得客户机端请求参数(客户端提交的数据)
getParameter(String)方法(常用):获取指定参数的值
getParameterValues(String name)方法(常用):获取指定参数的所有的值
getParameterNames()方法(不常用):获取所有的请求参数
getParameterMap()方法(编写框架时常用):获取所有的请求参数和对应的值

代码如下所示:

/**
 * Servlet implementation class RequestServlet
 * 演示request的各种常用方法
 */@WebServlet("/RequestServlet")publicclassRequestServletextendsHttpServlet{privatestaticfinallongserialVersionUID=1L;/**
     * @see HttpServlet#HttpServlet()
     */publicRequestServlet(){super();// TODO Auto-generated constructor stub
}​/**
     * @see 处理GET请求
     */protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//编码格式
//request.setCharacterEncoding("UTF-8");
//获取参数方法
System.out.println(request.getParameter("name"));System.out.println(Arrays.toString(request.getParameterValues("name")));System.out.println(request.getParameterMap());System.out.println(request.getParameterNames());//获取请求方法
System.out.println("getMethod--->"+request.getMethod());//获取远程ip地址
System.out.println(request.getRemoteAddr());//获取远程端口号
System.out.println(request.getRemotePort());System.out.println(request.getRemoteHost());System.out.println(request.getRemoteUser());System.out.println("getRequestURL:"+request.getRequestURL());System.out.println("getContextPath:"+request.getContextPath());System.out.println("getServletPath--->"+request.getServletPath());System.out.println("getServerName--->"+request.getServerName());Enumeration<String>ets=request.getHeaderNames();while(ets.hasMoreElements()){Stringkey=ets.nextElement();System.out.println("请求消息头:key="+key+"---值:"+request.getHeader(key));}}​/**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{// TODO Auto-generated method stub
//doGet(request, response);
}}

8.6.2 HttpServletResponse

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
向客户端(浏览器)发送响应头的相关方法:
 addDateHeader:把给定的名字和日期值加入到响应的头部 
 addHeader:给定的名字和和数值加到响应的头部
 addIntHeader:将给定的名字和整数值加到一个相应的头部
 containsHeader:是否指定的响应消息头部已被设置过了
 setDateHeader:设置带有给定的名字和数值的响应消息头  
 setHeader:设置带有给定的名字和数值的响应消息头
 setIntHeader:设置带有给定的名字和整数值的响应消息头
 setContentType:设置响应内容的格式
 addCookie:新增Cookie
设置状态响应码:
setStatus:设置Http协议的状态响应码
负责向客户端(浏览器)发送数据的相关方法:
getOutputStream:获取输出字节流向客户端写出内容
getWriter:获取输出字符流向客户端写出内容
URL重定向:
encodeURL:可以对url进行重定向,也就是将JSESSIONID传递

代码如下所示:

/**
 * Servlet implementation class ResponseServlet
 * 演示response常用的方法
 */@WebServlet("/ResponseServlet")publicclassResponseServletextendsHttpServlet{privatestaticfinallongserialVersionUID=1L;/**
     * @see HttpServlet#HttpServlet()
     */publicResponseServlet(){super();// TODO Auto-generated constructor stub
}​/**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//编码格式
//request.setCharacterEncoding("");//设置请求内容的编码格式
response.setCharacterEncoding("UTF-8");//设置响应数据的编码格式
response.setStatus(404);//设置状态响应码
//设置响应内容的类型和编码格式
response.setContentType("text/html;charset=UTF-8");//response.getOutputStream();
//获取打印字符流
PrintWriterpw=response.getWriter();pw.println("困了");pw.println("站起来");pw.close();System.out.println("OK");}/**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{// TODO Auto-generated method stub
doGet(request,response);}}

二.jsp

1 JSP技术的特征

JSP技术所开发的web应用程序是基于Java的,它拥有Java跨平台的特性,以及业务代码分离,组建重用,基础Java servlet功能和预编译功能。

1)跨平台

由于JSP是基于Java语言的,因而它可以使用Java的API,所以也是跨平台的,可以应用在Windows、Linux、Mac和Solaris。

2)业务代码分离

采用JSP开发的项目,通常使用HTML语言来设计和格式化静态页面内容,而使用JSP标签来实现动态部分,业务代码通常使用servlet、struts、springmvc等业务控制层来处理,从而实现业务层和视图层分离,这样,JSP只负责显示数据即可,这样,修改业务代码不会影响JSP页面代码。

3)组件重用

JSP中,可以使用JavaBean编写业务组件,也就是使用一个JavaBean封装业务处理代码或者作为一个数据处理模型,这个JavaBean可以重复使用,也可以应用到其他应用程序中。

4)继承Java servlet功能

JSP的本质是servlet,因此说JSP拥有servlet的所有功能。

5)预编译

用户首次通过浏览器访问JSP页面时,服务器对JSP页面代码进行编译,并且仅执行一次编译,编译后被保存,下次访问时直接执行编译过的代码,节约了服务器资源,提升了客户端访问速度。

2 JSP技术的原理

JSP的工作方式是请求/应答模式,客户端发出HTTP请求,JSP收到请求后进行处理,并返回处理结果。在一个JSP文件首次被请求时,JSP引擎首先把这个JSP文件转换成一个servlet,而该引擎本身也是一个servlet。运行过程如下:

1)JSP引擎首先把该JSP文件转换成一个Java源文件(servlet),在转换时,如果发现JSP文件中有任何语法错误,则中断转换过程,并向服务端和客户端输出错误信息。

2)如果转换成功,JSP引擎用javac把该Java源文件编译成相应的class文件。

3)创建一个servlet(JSP页面的转换结果)实例,该servlet的jspInit()方法被执行,jspInit()方法在servlet生命周期中只调用一次。

4)用jspService()方法处理客户端的请求。对每一个请求,JSP引擎创建一个新的线程来处理。如果多个客户端同时请求该JSP文件,则JSP引擎会创建多个线程来处理每个请求。由于该servlet始终驻留与内存,所以可以非常迅速的响应客户端的请求。

5)如果JSP文件被修改了,服务器将根据设置决定是否对该文件重新编译,如果需要重新编译,则将以编译结果取代内存中的servlet,并继续以上过程。

6)虽然JSP的效率很高,但首次调用时,由于需要转换和编译,会有一些轻微的延迟。此外,在任何时候,由于系统资源不足的原因,JSP引擎将以某种不确定的方式将servlet中从内存中移去。在此情况下,jspDestroy()方法首先被调用,然后servlet实例将被回收。

在jspInit()中可进行一些初始化工作,如建立与数据库的连接或其他配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值