JavaWeb----知识点总结
今天终于听完了b站300p的javaweb课程,今天我写一篇关于javaweb知识点总结的博客(又水了一篇)。
我们学校正好这学期也学javaweb,我只有把javaweb复习踏实了然后再复习一下javaSE才敢碰框架,要不然真不敢盲目学框架。
首先明确一点javaweb三大件:servlet程序,filter过滤器,listenner监听器。
我先来着重讲解一下servlet程序。(jsp、JSTL、EL表达式后面会提)
当然了,想要写出一个javaweb项目还不能缺少和数据库的交互,底下两个链接分别是JDBC底层和JDBC在项目实战的运用:
一、servlet程序
首先来介绍一下在javaweb中的路径问题,路径的一般形式:
http://localhost:8080/demo/
其中http是协议,localhost是服务器ip,8080是端口号,demo是工程名,同时也是artficats名,后面就是跟资源路径了。
servlet程序也是有生命周期的:
/** * @author 陈柏宇 * * servlet生命周期 * 1、执行servlet构造器方法 * 2、执行init初始化方法 * 第一 二步是在第一次访问的时候servlet程序会调用 * 3、执行service方法 * 第三步每次访问都会调用 * 4、执行destroy方法 * web工程停止的时候才会执行第四步 */
一般在实际项目开发中,都是使用继承HttpServlet类的方法去实现Servlet程序
1、编写一个类去继承 HttpServlet类
2、根据业务需要重写 doGet 或者 doPost方法
3、到 web.xml中的配置Servlet访问程序
一个普通的servlet程序实例:
public class HelloServlet extends HttpServlet { private String message; public void init() { System.out.println("2、初始化方法"); } public HelloServlet() { System.out.println("1 构造器方法"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); // Hello PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>" + message + "</h1>"); out.println("</body></html>"); } public void destroy() { System.out.println("4、destroy销毁方法"); } /** * * @param req * @param res * @throws ServletException * @throws IOException * 执行你的功能代码 */ @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("3、service方法"); } private void doGet() { System.out.println("1get请求的操作"); } private void doPost() { System.out.println("post请求的操作"); } }
我们是这样在web.xml中配置的:
<!--给tomcat配置servlet程序--> <servlet> <!--给servlet程序起一个别名--> <servlet-name> HelloServlet </servlet-name> <servlet-class> com.example.demo.HelloServlet </servlet-class> </servlet> <!--给servlet程序配置一个访问地址--> <servlet-mapping> <!--告诉服务器当前配置的地址给哪个服务器使用--> <servlet-name>HelloServlet</servlet-name> <!--url pattern 标签配置访问地址 / 斜杠在服务器解析的时候表示地址为http://ip:port/工程路径 /hello 表示地址为:http://ip:port/工程路径/hello 一定要以/开头 --> <url-pattern>/hello</url-pattern> </servlet-mapping>
servlet中有一个很重要的成员:servletContext对象(servlet上下文对象)
那么什么是servlet上下文对象呢?
/** * 什么是ServletContext * 1、ServletContext是一个接口,他表示Servlet上下文对象 * 2、一个web工程,只有一个ServletContext对象实例 * 3、ServletContext对象是一个域对象 * 4、ServletContext对象在web工程启动的时候创建,停止的时候销毁,生命周期在整个工程运行期间 */
servlet对象是一个域对象,域对象就是指能像Map一样存取数据的对象,这里的域是指存取数据的操作范围,整个Web工程
这里我把Map和sevletContext对象做一下类比:
存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()
那么ServletContext类有哪些作用呢:
1、获取web.xml中配置的上下文参数 context-param 2、获取当前的工程路径 格式: /工程路径 3、获取工程部署后再服务器硬盘上的绝对路径 4、像Map 一样存取数据
首先介绍第一点:获取web.xml中配置的上下文参数 context-param
我们在web.xml中这样配置上下文参数:
<!--context-param 是上下文参数(它属于整个web工程)--> <context-param> <param-name>username</param-name> <param-value>context</param-value> </context-param> <!--context-param 是上下文参数(它属于整个web工程)--> <context-param> <param-name>password</param-name> <param-value>root</param-value> </context-param>
在servlet程序又是这样获取的:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、获取web.xml中配置的上下文参数 context-param ServletContext context = getServletContext();
String username = context.getInitParameter("username"); System.out.println("context-param参数username的值是:" + username); //context-param参数username的值是:context
System.out.println("context-param参数password的值是: " + context.getInitParameter("password")); //context-param参数password的值是:root //2、获取当前的工程路径 格式: /工程路径 System.out.println("当前工程路径:" + context.getContextPath()); //当前工程路径:/demo //3、获取工程部署后再服务器硬盘上的绝对路径 /* / 被服务器解析 地址为 : http://ip:port/工程名/ 映射到idea代码的web目录<br/> */ System.out.println("工程部署的路径::" + context.getRealPath("/")); //工程部署的路径::C:\Users\HASEE\Desktop\apache-tomcat-8.5.70\webapps\WebProjects\demo\target\demo-1.0-SNAPSHOT\ }
在浏览器我们打开 开发者模式可以在NetWork(我用的谷歌浏览器)中查看请求头的信息:
常用请求头有:
常用请求头: Accept 表示客户端可以接受的数据类型 Accept-Language 表示客户端可以接收的语言类型 User-Agent 表示客户端浏览器的信息 Host:表示请求时的服务器ip和端口号
客户端(浏览器)和服务器的交互方式可以通过get请求和post请求来体现
那么get请求和post请求有哪些区别呢:
请求方式:
Get请求有哪些: 1.form标签,method = get 2.a标签 3.link标签引入css 4.script标签引入js文件 5.img标签引入图片 6.iframe引入html页面 7.浏览器地址栏中输入地址后输入回车
post请求: 1.form标签 method = post
传输数据的大小:
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。
但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。
因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
安全性:
POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。
比如,在进行登录操作,通过GET请求,用户名和密码都会暴露在URL上了。
综上,虽然get请求方式比post请求方式多,但并不能说明get请求比post方式好,我们在项目中很多时候都用的post请求。
接下来看看响应的HTTP协议格式:
响应的http协议格式 1.响应行 (1)相应的协议和版本号 (2)相应状态码 (3)相应状态描述符 2.响应头 key : value 不同响应头有其不同的含义 Server : 表示服务器的信息 Content-Type : 表示响应体的数据类型 空行 3.响应体 ---->>> 就是回传给客户端的数据
常见的响应码格式(就是大家最讨厌的404哪些东西):
常见的响应码说明: 200 请求成功 302 表示请求重定向 404 表示请求服务器已经收到,但是你要的数据不存在 (请求地址错误) 500 表示服务器已经收到请求但是服务器代码错误(内部错误)
话题再回到前面ServletContext上下文对象,我们如何使用这个域对象呢,我们之前已经介绍了setAttribute()方法和getAttribute对象了,我们是这样在程序中使用的:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //getServletConfig().getServletContext(); //获取ServletContext对象 ServletContext context = getServletContext(); System.out.println("保存之前: Context1 获取 key1的值是:"+context.getAttribute("key1")); //null context.setAttribute("key1","value1"); System.out.println("context1中获取域数据eky1的值是"+context.getAttribute("key1")); }
这里注意一下:
getServletConfig().getServletContext();
我这里先获得了Servlet的配置文件再获取上下文对象
其中ServletConfig也是一个类,它有如下作用:
ServletConfig 类 : 是 Servlet程序的配置信息类 Servlet程序和 ServletConfig对象都是由Tomcat负责创建,我们负责使用 Servlet程序默认是第一次访问时创建 ServletConfig是每个 Servlet程序创建时,就创建一个对应的 ServletConfig对象
三大作用 1、可以获取Servlet 程序的别名 servlet-name的值 2、获取初始化参数 init - param 3、获取ServletContext 对象
我在web.xml中这样定义:
<servlet> <servlet-name>ServletConfigTest</servlet-name> <servlet-class>com.example.demo.ServletConfigTest</servlet-class> <init-param> <!--是参数名--> <param-name>username</param-name> <!--是参数值--> <param-value>root</param-value> </init-param> <init-param> <!--是参数名--> <param-name>url</param-name> <!--是参数值--> <param-value>jdbc:mysql://3306/test</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletConfigTest</servlet-name> <url-pattern>/Test3</url-pattern> </servlet-mapping>
我在程序是这样写的:
public void init(ServletConfig servletConfig) throws ServletException { //别名是servlet - name System.out.println("ServletConfigTest的别名是:" + servletConfig.getServletName()); //ServletConfigTest的别名是:ServletConfigTest //初始化参数init-param System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username")); //初始化参数username的值是:root System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("url")); //初始化参数username的值是:jdbc:mysql://3306/test //获取ServletContext 对象 System.out.println(servletConfig.getServletContext()); //org.apache.catalina.core.ApplicationContextFacade@4b94c49d }
当我在启动服务器并在浏览器中输入:
http://localhost:8080/demo/Test3
控制台就会打印:
ServletConfigTest的别名是:ServletConfigTest 初始化参数username的值是:root 初始化参数username的值是:jdbc:mysql://3306/test org.apache.catalina.core.ApplicationContextFacade@6ff4bf1
可以发现前三行内容都是我们在web.xml定义的,而最后一行是上下文对象的地址。
我们可以注意到在Servlet程序中无论是get()方法还是post()方法都有两个不同参数:
HttpServletRequest对象,和HttpServletResopnse对象
前者是客户端给服务器的请求对象
后者是服务器给客户端的相应对象
关于requst对象:
/** * @author 陈柏宇 * HttpServletRequestTest类的作用: * 每次只要有请求进入tomcat服务器,Tomcat服务器就会把请求过来的http协议信息解析好封装到Request对象中 * 然后传递到service方法(doGet和doPost)中给我们使用 * 我们可以通过HttpServletRequest对象获取到所有请求的信息 * * 常用方法: * getRequestURI() : 获取请求的资源路径 * getRequestURL() : 获取请求的统一资源定位符 * getRemoteHost() : 获取客户端的ip地址 * getHeader() : 获取请求头 * getParameter() : 获取请求的参数 * getParameterValues() : 获取请求的参数(多个值的时候使用) * getMethod() : 获取请求的方式 GET 或 POST * setAttribute(key,value) : 设置域数据 * getAttribute(key) : 获取域数据 * getRequestDispatcher() : 获取请求转发对象 */
我们在web.xml中这样设置:
<servlet> <servlet-name>HttpServletRequestTest</servlet-name> <servlet-class>com.example.demo.HttpServletRequestTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>HttpServletRequestTest</servlet-name> <url-pattern>/request</url-pattern> </servlet-mapping>
并且写这样的一个html表单:
<form action="http://localhost:8080/demo/request" method="post"> 用户名:<input type="text" name = "username"><br/> 密 码:<input type="password" name="pwd"><br/> 兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++ <input type="checkbox" name="hobby" value="java">java <input type="checkbox" name="hobby" value="python">python<br/> <input type="submit"> </form>
再写一个这样的servlet程序:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); //设置请求体的字符集为utf-8,从而解决post请求中文乱码问题 System.out.println("--------Post-----------"); String username = req.getParameter("username"); System.out.println("获取用户名: "+username); String password = req.getParameter("pwd"); System.out.println("获取密码: " + password); String[] hobby = req.getParameterValues("hobby"); System.out.println("获取兴趣: " + Arrays.asList(hobby)); }
我们在表单中输入用户名为123,密码为123,三项全选
最终控制台输出:
--------Post-----------
获取用户名: 123
获取密码: 123
获取兴趣: [cpp, java, python]
这样就可以实现从浏览器获取数据到服务器上了。
那么我们如何在浏览器上写数据呢?
这里就要用到我们前面提到的HttpServletResponse类了:
首先来介绍一下这个类:
/** * HttpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对传递给 * Servlet程序去使用,HttpServletRequest表示请求过来的信息,HttpServletResponse表示响应的信息 * 我们如果需要设置返回给客户端的信息,就可以通过HttpServletResponse对象来进行设置 * * HttpServletResponse输出流的说明 * 字节流 getOutStream(); 常用于下载(传递二进制) * 字符流 getWriter(); 常用于回传字符串(常用) * 用了字节流,就不能再用字符流,反之一样 */
我们在往客户端回传字符的时候要注意,我们回传的如果是中文字符那就一定要设置字符集,
因为Tomcat服务器默认使用iso字符集(谁叫Tomcat服务器是美国人设计出来的呢,26个英语字母解决一切问题)
我们最好使用这种方法设计字符集:
resp.setContentType("text/html;charset=UTF-8"); //此方法一定要在获取流对象之前才有效
而后就可以放心在浏览器中输出中文字符了
PrintWriter writer = resp.getWriter(); //获取流对象 writer.write("你好"); //设置字符集后不会出现乱码
当然了,我们在web.xml要配置路径,具体我就省略了。
瑞了,明天讲请求转发和重定向。