1、Servlet
1.1、Servlet简介
. Servlet就是sun公司开发动态web的一门技术
·Sun在这些API中提供一个接口叫做: Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
。编写一个类,实现Servlet接口
。把开发好的Java类部署到web服务器中。把实现了Servlet接口的Java程序叫做 Servlet
idea maven连接本地仓时报错java.lang.RuntimeException: Cannot reconnect.
mvn dependency:resolve -Dclassifier=sources
2.HelloServlet
删掉刚才建好的项目的src文件,以后我们就在这个项目的基础上建自己的项目
配置一个完整的maven项目结构
添加一个java包,一个resources文件夹
3编写一个Servlet程序
1.编写一个普通的接口
2.实现Servlet接口,这里我们直接继承HttpServlet
package com.sophy.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
//用于get或者post只是请求实现的方式不同,可以相互调用,业务逻辑都一样;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了doGet方法");
// ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer= resp.getWriter();//响应流
writer.print("hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.编写Servlet的映射
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.sophy.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
5.配置Tomcat
注意:配置项目发布的路径
6.启动测试
7 、Servlet原理
Servlet是由Web服务器调用,web服务器在收到流浪器请求之后,会
8、Mapping问题
1.一个Servlet指定一个映射路径
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2.一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
3.一个Servlet可以指定通用映射路径
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
4.可以自定义后缀实现请求映射
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
这样不行,会报错:
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*.sophy</url-pattern>
</servlet-mapping>
这是可以的:
<!--<url-pattern>/hello.sophy</url-pattern>-->也是可以的
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.sophy</url-pattern>
</servlet-mapping>
9.优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
package com.sophy.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ErrorServlet extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>404<h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
配置ErrorServlet的映射
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.sophy.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
正确的路径
任何一个错误的路径
10、ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;
共享数据
我在这个Servlet中保存,可以在另外一个servlet中拿到;
package com.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("hello");
// this.getInitParameter() 初始化参数
// this.getServletConfig() Servlet配置
// this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String username="李白";
context.setAttribute("username",username);//将一个数据保存·在了ServletContext中,名字为username,值为username
}
}
package com.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GetServlet extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");//以一个html页面显示
resp.setCharacterEncoding("utf-8");//解决中文乱码问题
resp.getWriter().print("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.servlet.HelloServlet</servlet-class>
</servlet>
<!--请求的路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getContext</servlet-name>
<servlet-class>com.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getContext</servlet-name>
<url-pattern>/getContext</url-pattern>
</servlet-mapping>
</web-app>
http://localhost:8080/servlet04/getContext
http://localhost:8080/servlet04/hello/getContext
在hello页面之后写:
http://localhost:8080/servlet04/getContext
可以获取到数据
获取初化参数:
public class ServletDemo03 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在web.xml中注册
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
3.请求转发
public class ServletDemo04 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了ServletDemo04");
// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
// requestDispatcher.forward(req, resp);//调用forward实现请求转发
context.getRequestDispatcher("/gp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在web.xml中注册路径
<servlet>
<servlet-name>css4</servlet-name>
<servlet-class>com.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>css4</servlet-name>
<url-pattern>/css4</url-pattern>
</servlet-mapping>
因为是请求转发,请求地址并没有发生变化
11、读取资源文件properties
在java目录下新建properties。
在resources目录下新建properties。
发现:都被打包到了同一个路径下: classes,我们俗称这个路径为classpath;
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
//资源文件写在就java的包下面的情况
// InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/servlet/ab.properties");
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().print(username+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>pro</servlet-name>
<servlet-class>com.servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pro</servlet-name>
<url-pattern>/pro</url-pattern>
</servlet-mapping>
测试访问结果: