第2阶段 第14讲 Servlet进阶(下)

课程回顾

HttpServletResponse

  • 响应行:get HTTP1.1 url
  • 响应头: content-type content-length Location date
  • 响应体: response.getOutputStream() 字节流 response.getWriter() 字符流

HttpServletRequest

  • 获取请求行
  • 获取请求头
  • 获取请求体: request.getParameter( 表单的名称 ), request.getParameterValues( 多选框/只要name一致 ) ,request.getParameterNames() 获取所有的表单组件名称,再根据名称获取数据; request.getParameterMap()返回的是一个Map集合,key是表单组件的name, value是表单组件的value,value的类型是String[] 数据。
  • 获取远程客户端的信息
  • 获取本地服务器的信息
  • Local表示本地化信息: 国家、语言、日期格式、货币格式、数字格式

request作用域

作用域是一个对象的生命周期,有效的范围;request对象作用范围,request的生命周期非常短暂: 一个请求过来,执行Servlet,执行响应,响应结束该request作用域就结束。request对象可以携带任何类型数据,譬如: 到银行取钱,这是一个请求,该请求对象可以携带一些数据: ①存折②身份证③排队号码。等取款结束这些数据就失效。

作用域的相关方法:

setAttribute(String name, Object o) Stores an attribute in this request. 在该请求存储一个属性
removeAttribute(String name) Removes an attribute from this request.从该请求删除一个属性
getAttribute(String name)
Returns the value of the named attribute as an Object, or null if no attribute of the given name exists.返回一个Object,指定name的属性值; 如果给定的属性不存在返回null,。
getAttributeNames()
Returns an Enumeration containing the names of the attributes available to this request.
返回一个该request对象包含的所有有效的属性名称的枚举。

转发与重定向

重定向

response.sendRedirect( “success.jsp” ); 或者是一个Servlet地址,

http://localhost:8080/chapter14/login 可以看到浏览器地址栏变成 http://localhost:8080/chapter14/success.jsp

这个表示是浏览器重新发送一个请求。通过开发者工具可以清楚的看到两次请求,第一个login请求已经结束。
在这里插入图片描述

重定向案例

LoginServlet

package chapter14;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class LoginServlet extends HttpServlet{

	/**
	 * 序列化ID号: IO把对象存储到文件,游戏存盘,恢复游戏,读取把文件中的数据恢复成对象
	 * 保证ID号不能被随意更改, DNA
	 */
	private static final long serialVersionUID = -8887636083934406270L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("---------");
		req.setAttribute("idcard", "3242124463453452323");//存储身份证
		req.setAttribute("code", 100);//存储编号
		
		resp.sendRedirect("show");//重定向
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

ShowServlet

package chapter14;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/show")
public class ShowServlet extends HttpServlet {
	private static final long serialVersionUID = -1773135216278725123L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf8");
		PrintWriter out = resp.getWriter();
		out.println("<h1>欢迎登录系统</h1>");
		Object idcard = req.getAttribute("idcard");
		out.println("身份证号码:"+idcard);
		out.close();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

执行结果

在这里插入图片描述

并没有获取到数据,属性值;因为是两个不同的请求。生活中: 帅哥有一个请求:吃烩面,到一家酒店,但是酒店不提供餐饮服务;帅哥又到合记烩面饭店,这个可以完成。

转发

从一个页面转到另一个页面;生活案例: 一个请求,买票回家,转发过程: ①售票厅买票②到候车厅等待③检票④上车(检票)⑤下车出站(检票)。这个过程可以理解为转发请求的过程,回家从买票到上车到下车出站这是一个request对象。在request中存储的数据就可以获取到。

如何实现转发?重定向是 response.sendRedirect(),转发是通过RequestDispatcher 接口实现的。

LoginServlet修改如下:

package chapter14;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class LoginServlet extends HttpServlet{
	private static final long serialVersionUID = -8887636083934406270L;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("---------");
		req.setAttribute("idcard", "3242124463453452323");//存储身份证
		req.setAttribute("code", 100);//存储编号
		
		//resp.sendRedirect("show");//重定向
		//通过转发到ShowServlet
		//①获取请求转发器对象
		RequestDispatcher dis = req.getRequestDispatcher("show");
		//②执行转发,把请求和响应对象传递给ShowServlet
		dis.forward(req, resp);
        //req.getRequestDispatcher("show").forward(req, resp);//两步合并一步
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

执行效果:
在这里插入图片描述

通过执行效果可以看出:

  • 只发送一个请求 login
  • showServlet可以获取request作用域的属性值
  • 地址栏还是login请求,不是show

面试题: 转发和重定向的区别?

  1. 地点:转发是在服务器端实现、重定向是在客户端实现
  2. 数量:转发是一个请求,重定向是两个请求
  3. 地址:转发地址栏不变,重定向地址栏改变
  4. 数据:转发request存储的数据可以获取,重定向不可以获取request存储的数据
  5. 资源:转发只能在本系统内部,重定向可以是外部资源

doGet/doPost

Servlet在接收请求的时候,首先到的是HttpServlet的service方法,再根据请求的method调用子类的覆盖的方法。

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < lastModified) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

根据method的值进行分发请求,如果get调用doGet方法,如果post调用doPost方法。

作用域其他方法

package chapter14;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/show")
public class ShowServlet extends HttpServlet {
	private static final long serialVersionUID = -1773135216278725123L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println(request);
		response.setContentType("text/html;charset=utf8");
		PrintWriter out = response.getWriter();
		out.println("<h1>欢迎登录系统</h1>");
		Object idcard = request.getAttribute("idcard");
		out.println("身份证号码:"+idcard+"<br/>");
		//遍历属性
		Enumeration<String> en = request.getAttributeNames();
		while(en.hasMoreElements()) {
			String key = en.nextElement();
			Object value = request.getAttribute(key);
			out.println(key + "----->" + value + "<br/>");
		}
		//删除属性
		request.removeAttribute("code");
		
		Object code = request.getAttribute("code");
		out.println("删除之后<br/>序号:"+code);
		out.close();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

执行效果:
在这里插入图片描述

ServletConfig接口

config是配置的意思,ServletConfig就是Servlet的配置信息。

基于web.xml配置

package chapter14;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JDBCServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	/*
	//第1种方法
	private String url;
	private String username;
	private String password;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		url = config.getInitParameter("url");
		username = config.getInitParameter("username");
		password = config.getInitParameter("password");
	}
	*/
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		
		//第2种方法
		String url2 = getServletConfig().getInitParameter("url");
		String username2 = getServletConfig().getInitParameter("username");
		String password2 = getServletConfig().getInitParameter("password");
		/*
		resp.getWriter().println("url:"+ url + "<br>");
		resp.getWriter().println("username:"+ username+ "<br>");
		resp.getWriter().println("password:"+ password+ "<br>");
		resp.getWriter().println("<hr/>");
		*/
		resp.getWriter().println(url2 + "<br/>"+username2+"<br/>"+password2);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}

}

注意两种方法互斥。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>chapter14</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <!--  配置Servlet -->
  <servlet>
  	<servlet-name>jdbc</servlet-name>
  	<servlet-class>chapter14.JDBCServlet</servlet-class>
  	<!-- initial 初始化参数 -->
  	<init-param>
  		<description>url</description>
  		<param-name>url</param-name>
  		<param-value>jdbc:mysql://localhost:3306/db1</param-value>
  	</init-param>
  	<init-param>
  		<description>用户名</description>
  		<param-name>username</param-name>
  		<param-value>root</param-value>
  	</init-param>
  	<init-param>
  		<param-name>password</param-name>
  		<param-value>123456</param-value>
  	</init-param>
  </servlet>
  
  <!-- 配置Servlet映射信息 -->
  <servlet-mapping>
  	<servlet-name>jdbc</servlet-name>
  	<url-pattern>/jdbc</url-pattern>
  </servlet-mapping>
</web-app>

基于注解配置

package chapter14;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value = "/jdbc2",initParams = {
		@WebInitParam(name = "url", value = "jdbc:mysql://localhost:3306/db1"),
		@WebInitParam(name = "username", value = "迪丽热巴"),
		@WebInitParam(name = "password", value = "666")
})

public class JDBCServletAnnotation extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private String url;
	private String username;
	private String password;
	@Override
	public void init(ServletConfig config) throws ServletException {
		url = config.getInitParameter("url");
		username = config.getInitParameter("username");
		password = config.getInitParameter("password");
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf8");
		resp.getWriter().println("url:"+ url + "<br>");
		resp.getWriter().println("username:"+ username+ "<br>");
		resp.getWriter().println("password:"+ password+ "<br>");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}

}

其他Servlet访问

package chapter14;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/third")
public class ThirdServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String url = getServletConfig().getInitParameter("url");
		resp.getWriter().println("url=="+url);
	}
	
}

结果是null,说明Servlet配置信息是私有的,只有当前Servlet才可以访问到。

ServletContext接口

ServletConfig读取的配置信息是当前Servlet的配置信息,属于私有的配置。有些情况是多个Servlet可以共享的信息如何配置。每个人有自己的私有的钱包,但是还有银行的存款是多个人共享的。这个种配置信息通过ServletContext接口实现的;Spring框架就是使用的ServletContext接口实现配置文件的读取。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>chapter14</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <!-- 配置全局信息,针对整个web应用 -->
  <context-param>
  	<description>spring配置文件</description>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  
  <!--  配置Servlet  略-->
</web-app>

两个Servlet访问:

package chapter14;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/third")
public class ThirdServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String url = getServletConfig().getInitParameter("url");
		
		//访问全局配置信息
		ServletContext ctx = getServletContext();
		String file = ctx.getInitParameter("contextConfigLocation");
		resp.getWriter().println("spring: "+file);
		resp.getWriter().println("url=="+url);
	}
	
}

第二个Servlet

package chapter14;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/myContext")
public class MyServletContext extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//访问全局配置信息
		ServletContext ctx = getServletContext();
		String file = ctx.getInitParameter("contextConfigLocation");
		resp.getWriter().println("spring: "+file);
	}
}

两个不同的Servlet都可以访问到全局配置信息,也就是说context-param配置的是针对所有Servlet的。

常用方法

package chapter14;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/myContext")
public class MyServletContext extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=utf8");
		PrintWriter out = resp.getWriter();
		//访问全局配置信息
		ServletContext ctx = getServletContext();
		//获取初始化参数
		String file = ctx.getInitParameter("contextConfigLocation");
		//获取指定资源的真实路径
		String realPath = ctx.getRealPath("images/01.jpeg");
		//获取资源路径
		Set<String> sets = ctx.getResourcePaths("/");
		//读取配置文件
		InputStream in = ctx.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
		Properties prop = new Properties();
		prop.load(in);
        //获取项目的路径 /chapter14
        String contextPath = ctx.getContextPath();
		out.println("prop--url:"+prop.getProperty("url")+"<br/>");
		out.println("resourcePaths:"+sets+"<br/>");
		out.println("realPath: "+realPath+"<br/>");
		out.println("spring: "+file+"<br/>");
        out.println("contextPath: "+contextPath+"<br/>");
	}
}

ServletContext作用域

ServletContext也可以存储数据,还是request对象的几个方法:

setAttribute(String name, Object object)
Binds an object to a given attribute name in this ServletContext.
removeAttribute(String name)
Removes the attribute with the given name from this ServletContext.
getAttribute(String name)
Returns the servlet container attribute with the given name, or null if there is no attribute by that name.
getAttributeNames()
Returns an Enumeration containing the attribute names available within this ServletContext.

这个作用域最大的,超过request对象,生命周期伴随web应用的加载和停止;tomcat加载该web应用就会创建一个ServletContext对象,直到Tomcat停止web应用,或者Tomcat停止服务;ServletContext对象才销毁。生命周期最长所以不建议在该对象存储较大的数据,否则会一直占用服务器内存。所以不管是转发还是重定向该对象的数据都可以获取到。

存储数据

ServletContext ctx = request.getServletContext();
ctx.setAttribute("db", "数据库连接池对象");

获取数据

//获取ServletContext对象的数据
String db = (String) getServletContext().getAttribute("db");
out.println("全局作用域对象db:"+db +"<br/>");

不管是重定向还是转发都可以获取数据。

中文乱码解决

HTML页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>用户注册</h1>
<form action="reg" method="get">
用户账号: <input type="text" name="username"/>
<input type="submit" value="注册"/>
</form>
</body>
</html>

Servlet

package chapter14;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/reg")
public class RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置请求的编码
		request.setCharacterEncoding("utf8");
		response.setContentType("text/html;charset=utf8");
		PrintWriter out = response.getWriter();
		String username = request.getParameter("username");
		out.println(username);
		out.close();
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

通过执行结果可以看出,表单的post和get请求都不乱码。友情提醒: 根据客户的真实环境测试,特别是IE浏览器。

Servlet多方法请求

当多个人请求一个Servlet的时候怎么办? 加入一个请求标记,根据标记判断请求的方法。每一个模块创建一个Servlet即可,然后根据标记调用方法。

package chapter14;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置请求的编码
		request.setCharacterEncoding("utf8");
		response.setContentType("text/html;charset=utf8");
		//获取请求标记
		String flag = request.getParameter("flag");
		if("reg".equals(flag)) {
			reg(request,response);
		}else if("login".equals(flag)) {
			login(request,response);
		}else {
			PrintWriter out = response.getWriter();
			out.println("请求标记有误,请检查.");
			out.close();
		}
	}
	protected void reg(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		String username = request.getParameter("username");
		out.println("用户注册: " + username);
		out.close();
	}
	
	protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		PrintWriter out = response.getWriter();
		out.println("用户账号: " + username + "-用户密码:"+password);
		out.close();
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

注册页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>用户注册</h1>
<form action="userServlet" method="get">
<input type="hidden" name="flag" value="reg"/>
用户账号: <input type="text" name="username"/>
<input type="submit" value="注册"/>
</form>
</body>
</html>

登录页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>用户登录</h1>
<form action="userServlet?flag=login" method="post">
用户账号: <input type="text" name="username"/><br/>
用户密码: <input type="text" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>

Servlet3.0注解模式

就是servlet的配置不用web.xml文件,取而代之的是一组注解。

@WebServlet @WebInitParam

url-pattern设置

  1. /login login就是请求的名称
  2. /* 任意的url只要一层目录的结构都能定位到当前的Servlet
  3. *.action 或者 *.do 给请求增加一个后缀
  4. /abc/bcd 多级路径
  5. *.any 为了不让别人猜到url自定义一个专有后缀
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值