入坑Servlet的笔记
什么是web
web就是网站,它用来表示Internet主机上供外界访问的资源。
Internet供外界访问资源分为两大类:
* 静态资源:web页面的数据保持不变。(HTML,CSS)
* 动态资源:web页面的数据由程序产生,不同时间,不同的设备访问的内容
是不同的。(Servlet,JSP)
* 在java 中,动态web资源开发技术统称为 java web。
web服务器是什么
web服务器是运行及发布web应用的容器,只有将开发的web项目放到该容器中,才能使网络中所有的用户进行访问。我们初学者使用的Tomcat就是web服务器的一种,它主要是用来运行Servlet编写的程序。
什么是Servlet
概念
* servlet是服务器端的程序(代码,功能实现),可交互式的处理客户端发送到
服务器的请求,并完成操作响应。
* 动态页面技术
* javaweb程序开发的基础,狭义的servlet是指Java语言实现的一个接口,
广义的Servlet是指任何实现了这个Servlet的类。
Servlet核心接口和类
在servlet体系接口中,除了实现接口,还可以通过继承GenericServlet和HttpServlet类完成编写。(但一般我们都通过写继承HttpServlet来编写servlet)
servlet接口
在Servlet API中最重要的就是servlet接口 ,所有的servlet都会直接或间接
和该接口发生联系,或是直接实现该接口,或间接继承实现该接口的类。
Servlet接口包含以下5种方法:
public void init();
public ServletConfig getServletConfig() ;
public void service();
public String getServletInfo() ;
public void destroy() ;
GenericServlet抽象类
GenericServlet使编写servlet变得更加的简单。它提供了生命周期方法init
和destroy的简单实现。要编写一般的servlet只需要重写service方法即可。
HttpServlet类
HttpServlet是继承GenericServlet的进一步拓展,
提供将要被子类化以创建适用于web站点的httpServlet的抽象类。HttpServlet
的子类必须要重写其中的一个方法:
doGet,如果servlet支持http的get请求
doPost,用于httppost请求
doPut,用于http put请求
doDelete,用于http delete请求
servlet两种创建方式
实现servlet接口
public class MyServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("My First Web Project");
System.out.println(new Date());
System.out.println("123");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
继承HttpServlet 类(极力推荐)
public class HttpsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是doGet请求过来的内容");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是doPost请求过来的内容");
}
}
Servlet两种配置方式
使用web.xml
这里配置的是我们在启动tomcat网址在后面加上我们的配置来找到我们创建的web页面.像下面的例子我们配置的是myservlet,我们只需加上myservlet就能够找到我们创建的页面了。
<servlet>
<servlet-name>my</servlet-name>
<servlet-class>com.feng.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>my</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
<servlet>
url-pattern定义匹配原则:
精确匹配 /具体的名称 只有url路径是具体的名称的时候才会触发servlet
后缀匹配 *.xxx 只要是以xxx为后缀的就能触发servlet
通配符匹配 /* 匹配所有的请求,包含服务器的资源
通配符匹配 / 匹配所有的请求,包含服务器的资源,不包括jsp
load-on-startup (正整数或0)值越小,容器应用启动时加载这个servlet,
servlet优先级越高,越先启动。
如果元素是负整数或没写数字容器会servlet被请求后再
加载。
使用注解(极力推荐)
@Webservlet(value="/bs")
和上面一样启动tomcat在后面加个bs就能找到我们创建的页面。
@Webservlet常用属性:
* name:Servlet名字
* value:配置url路径,可以配置多个(value={“/bs”,"/hbs"})
* urlPatterns:配置url路径,和value一样不能同时使用
* loadOnStartup:配置servlet创建时机,如果是0或者正整数启动程序时
创建,如果是负数,访问时创建。数字越小,优先级越高
Servlet应用
request对象
在servlet中需要处理客户端的请求需要用到doGet()和doPost()方法的request
对象。
get和post区别
get请求:
* get提交的数据会放在URL的后面,以?分割URL和传输数据,参数之间用&
相连
* get方式明文传递,数据量小,不安全
* 效率高,浏览器默认请求为get请求
* 对应servlet是doGet()方法
post请求:
* post把提交的数据放在http包的body里
* 密文传递,数据量大,安全
* 效率没有get高
* 对应servlet是doPost()方法
request主要方法
方法名 | 说明 |
---|---|
String getParameter(String name) | 根据表单组件名称获取提交数据 |
void setCharacterEncoding(String charset) | 指定每个请求的编码 |
post中文乱码
由于客户端时utf-8的形式发送请求,服务端也需要以utf-8的形式接受。
//对request请求对象设置统一的编码
req.setCharacterEncoding("utf-8");
//设置编码格式,防止乱码
resp.setContentType("text/html;charset=utf-8");
response对象
response用于响应客户端请求并向客户端输出信息
方法名称 | 用途 |
---|---|
setHeader(name,value) | 设置响应信息头 |
setContentType(String) | 设置响应文件类型编码格式 |
setCharacterEncoding(String) | 设置服务端响应内容编码格式 |
getWrite() | 获取字符输出流 |
解决输出中文乱码
同时设置服务端的编码格式和客户端响应文件编码格式
resp.setContentType("text/html;charset=utf-8");
转发与重定向
一般我们使用转发是需要传递数据的,而使用重定向则不需要传递数据
在我们编写servlet时调用业务逻辑和结果页面显示不应该在同一个servlet里面,
这样会产生问题:
1.不符合单一职能,各司其职的思想
2.不利于后期的维护
所以我们需要将业务逻辑和显示结果分开
1.业务逻辑和显示结果分离后,如何跳转到显示结果的servlet里面呢?
2.业务逻辑得到的数据如何传递给显示页面的servlet中?
转发
转发是作用于服务器端,将请求转发给服务器的其他资源,以共同完成统一此请求。
页面跳转
request.GetRequestDispacher("/目标URL-pattern").forward(request,response);
使用forward跳转时,是在服务器内部跳转,地址栏不发生变化属于同一次请求。
通过页面跳转我们可以解决第一个问题。
数据传递
forward表示一次请求,是在服务器内部跳转,可以共享同义词request域中
的数据。
* request作用域:
拥有存储数据的空间,作用范围是一次请求有效(一次可以通过多次
转发)
* 可以将数据存入request中,在一次请求的任何位置获取
* 可以传递任何数据类型
* 存数据(业务逻辑的servlet)
request.setAttribute(key,value)
以键值对形式存储在request作用域中,key是String类型,value是Object类型
* 取数据(跳转到的servlet)
request.getAttribute(key)
通过String类型的key访问Object的value
重定向
重定向作用在客户端,客户端向服务端发送请求,服务端将一个新的地址传送
给客户端,客户端再凭借此地址发送一次新的请求。
页面跳转
在调用业务逻辑的servlet中,编写以下代码:
response.sendRedirect("目标URI");
URI:统一资源标识符,用来表示服务器中定位一个资源,资源在web项目中的路径。
数据传递
sendRedirect跳转时,地址栏改变,代表客户端重新发送请求。属于两次请求
* response没有作用域,两次request的数据无法共享
* 传递数据:通过URI的拼接进行数据传递("/WebProject/b?username=tom")
* 获取数据request.getParameter("username")
重定向特点
* 重定向是客户端行为
* 重定向是客户端至少做了两次请求
* 重定向浏览器的地址会发生改变
* 重定向可以指向任何的资源,