此博客用于个人学习,来源于网上,对知识点进行一个整理。
一,Servlet 配置方式:
1.全路径匹配:
url内的内容为 /a /b /a/b
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>servletTest.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/ServletTest</url-pattern>
</servlet-mapping>
http://localhost:8080/myServletRegister/ServletTest
2.路径匹配 , 前半段匹配:
以 / 开始 ,但是以 * 结束 /* /a/*,星号为其实是一个通配符,可以匹配任意文字。
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>servletTest.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/ServletTest/*</url-pattern>
</servlet-mapping>
http://localhost:8080/myServletRegister/ServletTest/123
3.以扩展名匹配:
没有/ ,以 * 开始,写法:*.扩展名 *.aa *.bb
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>servletTest.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>*.aa</url-pattern>
</servlet-mapping>
http://localhost:8080/myServletRegister/1234556/52465.aa
二,ServletContext:
每个 web 工程都只有一个 ServletContext 对象。 说白了也就是不管在哪个 servlet 里面,获取到的这个类的对象都是同一个。
1.作用:
1.获取全局配置参数:
//1.获取ServletContext对象
ServletContext context = getServletContext();
//2.调用方法获取全局参数
String parameter = context.getInitParameter("address");
System.out.println("第一个address=="+parameter);
在 xml 文件里面,位于所有的 servlet 标签前
<context-param>
<param-name>address</param-name>
<param-value>beijing..</param-value>
</context-param>
2.获取 web 工程中的资源:
-
获取资源在 tomcat 里面的绝对路径
如果想获取 web 工程下的资源,用普通的 FileInputSream 写法是不可以的,因为路径不正确,这里的路径是相对于 jre 来确定的,但是我们这是一个 web 工程,jre 后面有 tomcat 管理,所以这里真正的路径是 tomcat 上的 bin 目录。
//1.获取context对象
ServletContext context = getServletContext();
//2.调用方法:String getRealPath(String path):找出绝对路径
String path = context.getRealPath("file/config.properties");
//3.创建属性对象
Properties properties = new Properties();
InputStream is = new FileInputStream(path);
properties.load(is);
//4.获取属性的值
String name = properties.getProperty("name");
System.out.println("name1=="+name);
is.close();
String getRealPath(String path) 解析:
此时的相对路径:
D:\真Java\20180605java就业视频-最新\09.XML&tomcat(共28集)\源码笔记\code&资料\资料\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\ServletContextDemo
path:
file/config.properties
最终路径 = 绝对路径 + path:
D:\真Java\20180605java就业视频-最新\09.XML&tomcat(共28集)\源码笔记\code&资料\资料\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\ServletContextDemo/file/config.properties
- 获取资源流对象:
try {
//1.获取ServletContext对象
ServletContext context = getServletContext();
//2.创建属性对象
Properties properties = new Properties();
//3.通过方法:InputStream getResourceAsStream(String path)来获取web工程下的资源,转化成流对象。前面隐藏当前工程的根目录。
InputStream is = context.getResourceAsStream("file/config.properties");
properties.load(is);
//4.获取name属性的值
String name = properties.getProperty("name");
System.out.println("name2==" + name);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
路径情况与上一种是一致的。
- 通过 classloader 获取 web 资源:
try {
//1.创建属性对象
Properties properties = new Properties();
//2.通过方法: this.getClass().getClassLoader()调用方法:InputStream getResourceAsStream(String path)来获取web工程下的资源
InputStream is = this.getClass().getClassLoader().getResourceAsStream("../../file/config.properties");
properties.load(is);
//3.获取name属性的值
String name = properties.getProperty("name");
System.out.println("name3=="+name);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
此时的相对路径:
D:\真Java\20180605java就业视频-最新\09.XML&tomcat(共28集)\源码笔记\code&资料\资料\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\ServletContextDemo\WEB-INF\classes
应该退出到ServletContextDemo这个文件夹,使用…/进行文件的上一级,本次使用两个。
../../file/config.properties
最终路径:
D:\真Java\20180605java就业视频-最新\09.XML&tomcat(共28集)\源码笔记\code&资料\资料\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\ServletContextDemo/file/config.properties
3.使用 ServletContext 存取数据:
通过一个小案例进行示范
- 在 WebContent 文件夹下面构建一个登录页面 login.html:
<body>
<h2>请输入个人信息,登录系统</h2>
<form action="loginServlet" method="get">
账号:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
- 定义一个 servlet,名字为 loginServlet.java
//对客户端和服务器端的信息进行转码操作,防止出现乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("gbk");
//1.获取提交信息的对象
String username = req.getParameter("username");
String password = req.getParameter("password");
//2.输出信息
System.out.println("username=="+username+" password=="+password);
//3.进行校验(发送信息至客户端)
PrintWriter pw = resp.getWriter();
if(username.equals("admin") && password.equals("123")) {
pw.write("<h1>登录成功</h1>");
}else {
pw.write("<h1>登录失败</h1>");
}
-
进行第一步改进,如果登录成功就跳转到成功的页面
成功页面:
<h2>登录成功</h2><br>
<a href="">点击获取登录次数</a>
loginServlet.java 进行优化:
//1.设置状态码
resp.setStatus(302);
//2.进行页面跳转
resp.setHeader("Location", "login_success.html");
-
进行第二步改进,计算登录次数,并且出现页面提示:
创建一个 Servlet,名为 CountServlet.java,用于成功登录次数的发送:
//1.获取次数
int count = (int) getServletContext().getAttribute("count");
//2.进行页面的提示
resp.getWriter().write("登录成功的次数:"+count+"次");
- ServletContext 存取值分析:
2.ServletContext 何时创建, 何时销毁?
服务器启动的时候,会为托管的每一个 web 应用程序,创建一个 ServletContext 对象。
从服务器移除托管,或者是关闭服务器。
3.ServletContext 的作用范围:
只要在这个项目里面,都可以取。只要同一个项目。 A项目存,在B项目取,是取不到的,ServletContext 对象不同。
三,HttpServletRequest:
这个对象封装了客户端提交过来的一切数据。
1.可以获取客户端请求头信息:
demo01.java 内:
//1.通过Enumeration getHeaderNames()方法得到头信息的集合
Enumeration<String> headers = req.getHeaderNames();
//2.对集合进行遍历
while(headers.hasMoreElements()) {
String name = headers.nextElement();
String value = req.getHeader(name);
System.out.println("name=="+name+" value=="+value);
}
2.获取客户端提交过来的数据:
demo01.java 内:
//获取客户端提交的数据
String name = req.getParameter("name");
String address = req.getParameter("address");
System.out.println("name=="+name+" address=="+address);
使用时,输入网址:
http://localhost:8080/HttpServletResquestDemo/demo01?name=zhangsan&address=beijing
如果一个变量有多个值,可以通过 map 集合来获取数据:
//获得一个map集合
Map<String, String[]> map = req.getParameterMap();
Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
System.out.println("长度为:"+map.get(key).length);
String value1 = map.get(key)[0];
String value2 = map.get(key)[1];
String value3 = map.get(key)[2];
System.out.println("value1:"+value1+" value2:"+value2+" value3:"+value3);
}
使用时,输入网址:
http://localhost:8080/HttpServletResquestDemo/demo01?name=zhangsan&name=lisi&name=wangwu
3.获取中文数据的细节——乱码:
客户端提交数据给服务器端,如果数据中带有中文的话,有可能会出现乱码情况,那么可以参照以下方法解决。
1.GET 方式:
- 代码转码
//get请求过来的数据,在url地址栏上就已经经过编码了,所以我们取到的就是乱码,
//tomcat收到了这批数据,getParameter 默认使用ISO-8859-1去解码
//先让文字回到ISO-8859-1对应的字节数组 , 然后再按utf-8组拼字符串
username = new String(username.getBytes("ISO-8859-1") , "UTF-8");
System.out.println("userName="+username+"==password="+password);
-
在 tomcat 里配置
可以在 tomcat 里面做设置处理 conf/server.xml 加上URIEncoding=“utf-8”
<Connector connectionTimeout=“20000” port=“8080” protocol=“HTTP/1.1” redirectPort=“8443” URIEncoding=“UTF-8”/>
2.POST 方式:
这行设置一定要写在 getParameter 之前,这个是设置请求体里面的文字编码。get 方式不能使用这一行 ,get 方式是在地址栏进行代码的解码。
request.setCharacterEncoding("UTF-8");
四,HttpServletResponse:
返回数据给客户端。
1.Responsec 的一些常用方法:
- 用于写数据:
分为字符流和字节流,只是传输文字数据,两种方式都一样,如果是传输文件,只能用第二种。
//以字符流的方式写数据
response.getWriter().write("<h1>hello response...</h1>");
//以字节流的方式写数据
response.getOutputStream().write("hello response2222...".getBytes());
- 其他方法:
//设置当前这个请求的处理状态码
response.setStatus("");
//设置一个头
response.setHeader(name, value);
//设置响应的内容类型,以及编码。
response.setContentType(type);
2.响应数据出现中文乱码:
- 字符流输出:
response.getWriter()
//这里写出去的文字,默认使用的是ISO-8859-1 ,我们可以指定写出去的时候,使用什么编码写
//1. 指定输出到客户端的时候,这些文字使用UTF-8编码
response.setCharacterEncoding("UTF-8");
//2. 直接规定浏览器看这份数据的时候,使用什么编码来看。
response.setHeader("Content-Type", "text/html; charset=UTF-8");
response.getWriter().write("字符流输出");
- 字节流输出:
response.getOutputStream()
//1. 指定浏览器看这份数据使用的码表
response.setHeader("Content-Type", "text/html;charset=UTF-8");
//2. 指定输出的中文用的码表,getBytes()方法默认UTF-8的编码
response.getOutputStream().write("字节流输出".getBytes("UTF-8"));
- 两种方式都适合的方法:
开发中常用
response.setContentType("text/html;charset=UTF-8");
3.演练下载资源:
index.html:
<h3>点击下载数据</h3><br>
<a href="demo01?filename=aa.jpg">aa.jpg</a><br>
<a href="demo01?filename=bb.txt">bb.txt</a><br>
<a href="demo01?filename=cc.rar">cc.rar</a>
download/demo01.java:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取下载的文件名字
String filename = request.getParameter("filename");
//2.获取文件的绝对路径,切记加上/
String path = getServletContext().getRealPath("download/"+filename);
//3.出现下载页面,而不是简单访问
response.setHeader("Content-Disposition", "attachment; filename="+filename);
//4.转化成输入流和输出流
InputStream is = new FileInputStream(path);
OutputStream os = response.getOutputStream();
int len = 0;
byte[] bys = new byte[1024];
while((len = is.read(bys))!=-1) {
os.write(bys,0,len);
}
is.close();
os.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
4.下载中文数据:
download/demo01.java:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取下载的文件名字
String filename = request.getParameter("filename");
//出现中文的情况
filename = new String(filename.getBytes("ISO-8859-1") , "UTF-8");
System.out.println("filename="+filename);
//2.获取文件的绝对路径
String path = getServletContext().getRealPath("download/"+filename);
//对中文的名字进行编码
filename = URLEncoder.encode(filename,"UTF-8");
//3.出现下载页面,而不是简单访问
response.setHeader("Content-Disposition", "attachment; filename="+filename);
//4.转化成输入流和输出流
InputStream is = new FileInputStream(path);
OutputStream os = response.getOutputStream();
int len = 0;
byte[] bys = new byte[1024];
while((len = is.read(bys))!=-1) {
os.write(bys,0,len);
}
is.close();
os.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}