Servlet原理
Mapping问题
1.一个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>/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>
3.一个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>
5.可以自定义后缀实现请求映射
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.jxr</url-pattern>
</servlet-mapping>
*前面不能加项目映射的路径
6.优先级问题
固有的映射路径(指定的)的优先级最高,其次是默认的
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.jxr.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
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("<h>404</h>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
ServletContext
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter(); 初始化参数
//this.getServletConfig(); Servlet配置
//this.getServletContext(); Servlet上下文
ServletContext servletContext = this.getServletContext();
System.out.println("Hello");
}
}
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext的对象,它代表了当前的web应用。
ServletContext的作用:
1.共享数据:ServletContext实现servlet之间的数据共享
编写一个新的servlet,并修改HelloServlet,去获得attribute
public class HelloServlet extends HttpServlet {
@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 = "简绪睿";//数据
context.setAttribute("username",username);//将一个数据保存在ServletContext中,Attribute是个键值对形式,即名字为
//"username",而值为username.
}
}
<?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-name>hello</servlet-name>
<servlet-class>com.jxr.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.jxr.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getcontext</servlet-name>
<url-pattern>/getcontext</url-pattern>
</servlet-mapping>
</web-app>
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.getWriter().print("username"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
运行服务器,如果先进入/getcontext则得到null,所以得先运行/hello再运行/getcontext
2.获取初始化参数
在web.xml里面可以设置一些参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql//localhost:3306</param-value> //jdbc连接数据库的api
</context-param>
<servlet>
<servlet-name>geturl</servlet-name>
<servlet-class>com.jxr.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>geturl</servlet-name>
<url-pattern>/geturl</url-pattern>
</servlet-mapping>
public class ServletDemo03 extends HttpServlet {
@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 {
}
}
3.请求转发
可以转发页面
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了demo04");
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/geturl");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forwa实现请求转发;
//context.getRequestDispatcher("/geturl").forward(req,resp);一行也能完成
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.jxr.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
这里是因为通过requestDispatcher转发的/geturl页面
转发路径不变,但是重定向路径会发生改变。
上图是转发的流程,而下图是重定向的流程。
4.读取资源文件
在resources文件下建立properties
创建PropertiesServlet
public class PropertiesServlet extends HttpServlet{
public void test(){
Properties properties = new Properties();
}
}
然后使用maven清空target,启动tomcat观察properties的路径
若在com.jxr.servlet的文件下创建properties,则target里没有properties,因为maven在导出资源的时候会资源过滤,就如之前博客所说的,要在pom里面配置。
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</excludes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
记得重启idea
Properties:
1.在java目录下新建properties
2.在resources目录下新建properties
发现都被打包到同一个路径:class,我们俗称这个为classpath,即类路径
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop= new Properties();
prop.load(is);
String username = prop.getProperty("username");
String password = prop.getProperty("password");
resp.getWriter().print(username + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
get.ResourceAsStream()变成文件流
测试是否能获得db.properties的内容