Servlet原理
Servlet是由Web服务器调用,Web服务器在收到浏览器请求之后,会:
Mapping问题
一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</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>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>
一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
默认请求路径映射
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
自定义后缀实现请求映射,注意点,*前面不能加映射的路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.zzc</url-pattern>
</servlet-mapping>
errorservlet例子:
package com.kuang.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 ErrorServlet extends HttpServlet {
@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);
}
}
//在servlet请求文件中写上:
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
优先级问题:指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前web应用;
- 共享数据:我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter() 初始化参数
// this.getServletConfig() Servlet配置
// this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String username = "zzc";//数据
context.setAttribute("username", username);//将一个数据保存在了ServletContext中,名字为:username、值:username
System.out.println("Hello");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//该步骤用于获取servlet01存放的context
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
//下面两个是用来识别中文汉字,以至于不会出现乱码
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
//注意在获取context前,首先需要让servlet01放入数据,我们再访问servlet02的网络
resp.getWriter().println("名字"+username);
}
<!--先访问hello-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--再访问getc-->
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.kuang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
测试访问结果:
- 获取初始化参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//该步骤用于获取servlet01存放的context
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
- 请求转发
他路径是sd4,但是请求了/gp,所以就显示了gp的内容
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.kuang.servlet.ServletDome04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
//调用forward实现请求转发;
requestDispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
转发概念:
重定向概念:
- 读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到同一路径下:classes,我们俗称这个路径为classpath
思路:构建一个 文件流
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>com.kuang.servlet.ServletDome05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//该步骤用于获取所需东西,然后把资源变成一个流
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");//第一个/表示模块路径(当前web项目)
Properties prop= new Properties();
//load()加载数据
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}