页面乱码问题
获数据乱码
在使用form标签的时候,如果在表单中写入中文,读取数据时候容易出现乱码
原因:产生乱码,就是因为服务器与客户端之间编码不一致造成
解决方案:就是在客户端和服务器之间设置统一编码集
PS:在Tomcat7以下,如果客户端使用UTF-8编码传输数据到服务器,而服务器使用request对象来获取数据默认的编码集是ISO-8859-1,一定会出现乱码,Tomcat8之后传输数据,基本上就不会再出现乱码—》这个请求发送过程使用是GET请求
解决方案1:
在获取中文表单数据时候进行强制转换
String username = request.getParameter("username");
username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
PS:由于客户端使用也会使用post请求发送数据,客户端使用UTF-8发送数据到服务器端,因为服务器端也需要使用同一的UTF-8编码接收,我们就可以进行一个统一的编码设置,因为Tomcat8中虽然已经修复了Get请求中中文乱码问题,但是post没有修饰
解决访问2:
//设置请求参数的编码格式
request.setCharacterEncoding("UTF-8");
输出数据的时候
返回数据到页面的时候回出现乱码问题,原因在于浏览器识别不到返回的中文是什么编码格式,所以默认使用了GB2312编码集解码,必然产生乱码
代码解决乱码
/**
方式1(强烈推荐)
这些写返回时一个页面,并且是以UTF-8解码的
这样写也就相当于将数据写入到HTML文件中boby标签中,并且使用UTF-8形式展示
*/
response.setContentType("text/html;charset=UTF-8");
/**
方式2(不太推荐)
需要设置单独的编码集,并且使用响应头设置浏览器编码集
*/
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type","text/html;charset=UTF-8");
Servlet与JDBC集成
1.实现注册信息提交
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<h1>用户注册</h1>
<form action="/Java2002_web_servlet02/registerServlet" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd"></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="repwd"></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="email" name="email"></td>
</tr>
<tr>
<td>性别:</td>
<td>
男<input type="radio" name="gender" value="男" checked>
女<input type="radio" name="gender" value="女" >
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
<input type="reset" name="重置">
</td>
</tr>
</table>
</form>
</body>
</html>
2.Servlet实现
package com.qfedu.servletAndJDBC;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.注册解决编码问题
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//2.获取请求数据-->请求是request即 客户端向服务器发送数据
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
String repwd = request.getParameter("repwd");
String email = request.getParameter("email");
String gender = request.getParameter("gender");
//3.验证数据数据是否合法
//如何将数据写入到前端页面
PrintWriter writer = response.getWriter();//这个打印流可以将数据写到到前端页面中
if(username == null || username.trim().equals("")){
//只能将数据打印到控制台上
//System.out.println("用户不合法");
writer.println("用户名不合法");
//既然是流,除了本身有println方法之外,依旧提供write方法但是这个两个方法有一些区别【JSP中说】
return;
}
if(pwd==null || pwd.trim().equals("")){
writer.println("密码不合法");
return;
}
if(!pwd.equals(repwd)){
writer.println("两次面不一致");
return;
}
//保存数据到数据库中
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
//1.获取驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");
//3.创建预编译语句对象
preparedStatement = connection.prepareStatement("insert into t_user(username,password,email,gender) values(?,?,?,?)");
//4.设置参数
preparedStatement.setString(1,username);
preparedStatement.setString(2,pwd);
preparedStatement.setString(3,email);
preparedStatement.setString(4,gender);
//5.执行语句
int i = preparedStatement.executeUpdate();
if (i > 0){
writer.println("注册成功");
}else{
writer.println("注册失败");
}
} catch (Exception e) {
e.printStackTrace();
writer.println("注册失败");
}finally {
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
页面跳转
作为后台开发人员,在大多数时候都是在接收处理用户请求,并给予用户响应,为了方便操作,服务器端会将请求和响应封装成两个对象【request和response】,接下来就详细的讲解这个操作
Java Web服务器端控制页面跳转有两种方式:【重定向和转发】
重定向
请求重定向,是指客户端(web浏览器)向服务器发送请求,然后服务器告诉客户端,我会给以一个地址,你去访问这个新的地址,这个过程就是请求重定向(ps:因为是请求重定向,所以之前地址会被废弃)
例如:大宝向智哥借钱500元,但是我没钱,我说你可以找张校借钱
这里发生了如下操作:
大宝向智哥发起了一次请求,智哥响应了这个请求,具体响应是让大宝去找张校
大宝在向张校发起借钱的请求
实现原理
重定向特点:
1.重定向是客户端行为
2.重定向是浏览器做了至少【两次】的访问请求(注意)
3.重定向浏览器地址栏会发生改变
4.重定向两次跳转之间传输信息会丢失(超出了request范围)【注意】
5.重定向可以指向任何资源,包括当前应用程序中其他资源,同一个站点上的其他应用程序汇总资源,其他站点资源
ps:传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录
实现请求重定向
1.提供一个html页面,方便使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<div>
<!--这个表单的提交操作是使用servelt完成跳转【动态跳转】-->
<form action="/Java2002_web_servlet02/login" method="post">
<label>账号:</label> <input type="text" name ="un"/><br/>
<label>密码:</label> <input type="password" name ="pw"/><br/>
<input type="submit" value="登录"/>
</form>
</div>
<!--通过a标签的超链接完成跳转【静态跳转】-->
<h5><a href="reg.html">还没注册账号</a></h5>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网站首页</title>
</head>
<body>
<h1>欢迎进入到XXXXX管理系统...........</h1>
</body>
</html>
package com.qfedu.sendRedirect;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取表单中提交的用户名称
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
String un = request.getParameter("un");
String pw = request.getParameter("pw");
if(un.equals("zhangsan") && pw.equals("123456")){
//开始重定向
/**
* ps:重定向中使用 / --》 相当于是 http://ip:port 【第一个位置】
* 重定向有两种方式
*第一种:设置状态码为302,表示重定向。然后设置响应头,说明新的地址在什么位置
* 繁琐比较麻烦不推荐
*/
// response.setStatus(302);
// //ps:后面在的这个位置就是 : http://ip:port/Java2002_web_servlet02/loginIndex.html
// response.setHeader("Location","/Java2002_web_servlet02/loginIndex.html");
/**
* 第二种 直接给定重定向地址即可以【强烈推荐】
*/
response.sendRedirect("/Java2002_web_servlet02/loginIndex.html");
}else{
writer.println("用户名和面错误");
}
}
}
请求转发
请求转发是指,服务器收到请求后,从一个资源跳转到另外一个资源叫做请求转换
例如: 大宝向智哥借钱500元,但是我没钱,你可以找张校说,我转身找到张校,说你有500元钱?张校借我500元钱,此时我把500元钱转交给了大宝
这里相当于: 大宝向智哥发起一次请求,此时我不处理吗,但是我找别人来处理这个请,并将处理过后请求接返回给大宝
转发的原理
实现原理:
客户浏览器发送http请求----》
web服务器接收此请求 ----》
调用内部的一个方法在容器的内部完成请求处理和转发动作 ----》
将目标资源发送给客户端
PS:在这里,转换的路径必须是同一个web容器下的URL,其不能专项其他的web路径上去,【中间传递的式自己容器内request】
在客户端浏览器地址栏中仍然是第一次访问的路径,客户感觉不到服务器做了转换
特点:
1.转发是服务器行为
2.转发式浏览器只做【一次】请求访问(重要)
3.转发浏览地址栏中地址不会发生改变
4.转换两次条件之间传输的信息不会丢失,所以可以用过request进行数据的传递(重要)
5.转发只能将请求转发给同一个WEB应用的组件
ps:如果创建 RequestDispatcher 对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录
请求转发实现
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<div>
<!--这个表单的提交操作是使用servelt完成跳转【动态跳转】-->
<form action="/Java2002_web_servlet02/login2" method="post">
<label>账号:</label> <input type="text" name ="un"/><br/>
<label>密码:</label> <input type="password" name ="pw"/><br/>
<input type="submit" value="登录"/>
</form>
</div>
<!--通过a标签的超链接完成跳转【静态跳转】-->
<h5><a href="reg.html">还没注册账号</a></h5>
</body>
</html>
servlet代码
package com.qfedu.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;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/login2")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取表单中提交的用户名称
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
String un = request.getParameter("un");
String pw = request.getParameter("pw");
if(un.equals("zhangsan") && pw.equals("123456")){
//请求转换
/*
通过getRequestDispatcher这个方法者转发路径
在请求转发路径中 / 相当于是 http://ip:port/工程名 【第一个位置】
下面这个路径 http://ip:port/Java2002_web_servlet02/loginIndex.html
请求转换不仅可以给 HTML地址 也可以给 servlet地址
forward 直接翻译 "向前的意思" ---》 作用是讲请求和相应参数进行传递下一个servlet
*/
//request.getRequestDispatcher("/loginIndex.html").forward(request,response);
request.getRequestDispatcher("/login").forward(request,response);
}else{
writer.println("用户名和面错误");
}
}
}
请求转换和请求重定向的区别
Servlet生命周期
Servlet也会想人类一样存在一个生命周期,这个生命周期类似于人类**【从怀胎—》出生—》婴儿—》儿童—》少年—》成年—》中年—》老年—》死亡】**
通过代码演示生命周期
package com.qfedu.ServletLifeCycle;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/LifeServlet")
public class LifeServlet extends HttpServlet {
public LifeServlet(){
super();
System.out.println("1.完成实例化");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("2.完成初始化");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("3.就绪/服务");
}
@Override
public void destroy() {
super.destroy();
System.out.println("4.销毁了");
}
}
⽣命周期的四个阶段
阶段⼀ 实例化(constructor)
实例化阶段是Servlet⽣命周期中的第⼀步,由Servlet容器调⽤Servlet的构造器创建⼀个具体的Servlet
对象的过程。⽽这个创建的时机可以是在容器收到针对这个组件的请求之后,即⽤了才创建;也可以在
容器启动之后⽴刻创建实例,⽽不管此时Servlet是否使⽤的上。使⽤如下代码可以设置Servlet是否在服
务器启动时就执⾏创建影响创建的时机
阶段⼆ 初始化(init)
Servlet在被加载实例化之后,必须要初始化它。在初始化阶段,init()⽅法会被调⽤。这个⽅法在
javax.servlet.Servlet接⼝中定义。其中,⽅法以⼀个ServletConfig类型的对象作为参数。ServletConfig
对象由Servlet引擎负责创建,从中可以读取到事先在web.xml⽂件中通过节点配置的多个name-value名
值对。ServletConfig对象还可以让Servlet接受⼀个ServletContext对象。
⼀般情况下,init⽅法不需要编写,因GenericServlet已经提供了init⽅法的实现,并且提供了
getServletConfig⽅法来获得ServletConfig对象。
ps:init⽅法只被执⾏⼀次
阶段三 就绪/服务(service)
Servlet被初始化以后就处于能够响应请求的就绪状态。每个对Servlet的请求由⼀个ServletRequest对象
代表,Servlet给客户端的响应由⼀个ServletResponse对象代表。当客户端有⼀个请求时,容器就会将
请求与响应对象转给Servlet,以参数的形式传给service⽅法。service⽅法由javax.servlet.Servlet定
义,由具体的Servlet实现HttpServlet将service⽅法拆分了。doGet和doPost
阶段四 销毁(destroy)
Servlet容器在销毁Servlet对象时会调⽤destroy⽅法来释放资源。通常情况下Servlet容器停⽌或者重新
启动都会引起销毁Servlet对象的动作,但除此之外,Servlet容器也有⾃身管理Servlet对象的准则,整个
⽣命周期并不需要⼈为进⾏⼲预
ServletConfig类
ServletConfig类从类名上看,就知道是Servlet程序的配置信息类
Servlet程序和ServletConfig对象都是由Tomcat负责创建的,我们赋值使用。
Servlet程序默认第一次访问的时候进行创建,ServletConfig是每个Servlet程序创建时,就创建一个对象
作用
1、可以获取Servlet程序别名【Servlet-name】的值
2、获取初始化参数 init-param
3、获取ServletContext对象
web.xml版本获取
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>ServletConfigDemo</servlet-name>
<servlet-class>com.qfedu.ServletConfig.ServletConfigDemo</servlet-class>
<!--这里可以进行init-param 初始化参数的配置【必须在servlet标签中】 这个标签可以有多个-->
<init-param>
<!--参数的名字-->
<param-name>username</param-name>
<!--参数的值-->
<param-value>root</param-value>
</init-param>
<init-param>
<!--参数的名字-->
<param-name>url</param-name>
<!--参数的值-->
<param-value>jdbc:mysql://localhost:3306/mydb1</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletConfigDemo</servlet-name>
<url-pattern>/scd</url-pattern>
</servlet-mapping>
</web-app>
package com.qfedu.ServletConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletConfigDemo extends HttpServlet {
//servletConfig对象实在init方法作为参数存在
@Override
public void init(ServletConfig config) throws ServletException {
//1.可以获取Servlet程序的别名
System.out.println("ServletConfigDemo程序的别名是:"+config.getServletName());
//2.获取初始化参数
System.out.println("初始化参数username的值是:"+config.getInitParameter("username"));
System.out.println("初始化参数url的值是:"+config.getInitParameter("url"));
//3.获取ServletContext对象
System.out.println("ServletContext对象:"+config.getServletContext());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
注解方式
package com.qfedu.ServletConfig;
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;
import java.io.IOException;
@WebServlet(name="ServletConfigDemo2",value="/scd2",initParams = {
@WebInitParam(name="username",value="root"),
@WebInitParam(name="url",value="jdbc:mysql://localhost:3306/mydb1")
})
public class ServletConfigDemo2 extends HttpServlet {
//servletConfig对象实在init方法作为参数存在
@Override
public void init(ServletConfig config) throws ServletException {
//1.可以获取Servlet程序的别名
System.out.println("ServletConfigDemo程序的别名是:"+config.getServletName());
//2.获取初始化参数
System.out.println("初始化参数username的值是:"+config.getInitParameter("username"));
System.out.println("初始化参数url的值是:"+config.getInitParameter("url"));
//3.获取ServletContext对象
System.out.println("ServletContext对象:"+config.getServletContext());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
package com.qfedu.ServletConfig;
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;
import java.io.IOException;
@WebServlet(name="ServletConfigDemo3",value="/scd3",initParams = {
@WebInitParam(name="username",value="root"),
@WebInitParam(name="url",value="jdbc:mysql://localhost:3306/mydb1")
})
public class ServletConfigDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//实际ServletConfig应用的位置
ServletConfig servletConfig = getServletConfig();
//1.可以获取Servlet程序的别名
System.out.println("ServletConfigDemo程序的别名是:"+servletConfig.getServletName());
//2.获取初始化参数
System.out.println("初始化参数username的值是:"+servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是:"+servletConfig.getInitParameter("url"));
//3.获取ServletContext对象
System.out.println("ServletContext对象:"+servletConfig.getServletContext());
}
}
ServletContext对象
ServeletContext对象是什么
1、ServletContext是一个接口,它表示Servlet上下文对象,代表当前整个应用程。【JSP中application】
ps:当web服务器启动的时候,会为每一个web应用程序创建一个【共享的存储区域】ServletContext也叫做【公共区域】,也就是同一个web应用程中,所有的Servlet和JSP都可以共享这个区域,ServletContext在web服务器启动的时候回创建,服务关闭的时候才会销毁。
2.一个web工程,只有一个ServletContext对象实例
3.ServletContext对象是一个【域】对象
ps:域对象,是可以向Map一样存储数据的对象就叫做【域对象】,这里的域指的是存取数据的操作范围,即整个web工程
域对象 | 存数据 | 取数据 | 删除数据 |
---|---|---|---|
ServletContext | setAttribute() | getAttribute() | removeAttribute() |
4.ServletContext是在web工程部署启动时候创建,在web停止的时候销毁
如果获取Servlet上下文对象
"方式一: GenericServlet提供了getServletContext()方法"
"方法二: ServletConfig提供了getServletContext()方法"
"方式三: HttpSession提供了getServletContext()方法"
ps:这个不能直接获取,需要使用 request.getSession().getServletContext()
"方式四: HttpServletRequest提供getServletContext()方法" 【比较推荐】
ServeltContext操作和特点
ps:这个操作只能在web.xml文件中使用,不能使用注解
【获取路径】和获取web.xml配置值
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--context-param标签配置参数它属于整个web工程-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>12345</param-value>
</context-param>
</web-app>
servlet程序
package com.qfedu.ServletContext;
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;
import java.io.IOException;
@WebServlet("/scdd")
public class ServletContextDemo extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取web.xml中context-param参数值
// ServletContext servletContext = req.getServletContext();
ServletContext servletContext = getServletConfig().getServletContext();
String username = servletContext.getInitParameter("username");
String password = servletContext.getInitParameter("password");
System.out.println(username+" "+password);
//2.获取当前工程路径,格式: /工程路径
/**
* 当前工程路径:/Java2002_web_servlet02
*/
System.out.println("当前工程路径:"+servletContext.getContextPath());
//3.获取工程部署路径【真实路径】
/**
* 工程部署的路径是:C:\IdeaProjects\Java2002_web_servlet02\out\artifacts\web_war_exploded\
* 工程下css目录的绝对路径:C:\IdeaProjects\Java2002_web_servlet02\out\artifacts\web_war_exploded\css
*ps:IDEA是自动整合Tomcat操作,它会自动创建路径运行tomcat程序
* 不会向其他编译器一样,其他编译执行tomcat,他们会将项目部署到webapps目录中
*
*/
System.out.println("工程部署的路径是:"+servletContext.getRealPath("/"));
System.out.println("工程下css目录的绝对路径:"+servletContext.getRealPath("/css"));
}
}
存储数据
提供两个Servlet程序
package com.qfedu.ServletContext;
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;
import java.io.IOException;
@WebServlet("/scdd1")
public class ServletContextDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向map一样进行数据存储,【所有servlet和JSP共享】
//1.获取ServletContext对象
ServletContext servletContext = request.getServletContext();
//2.在存储值之前进行一次打印
System.out.println("保存之前:servletContext获取key1的值是:"+servletContext.getAttribute("key1"));
//3.正常存储数据 key是String value是Object
servletContext.setAttribute("key1","value1");
//获取值
System.out.println("保存之后:servletContext获取key1的值是:"+servletContext.getAttribute("key1"));
}
}
package com.qfedu.ServletContext;
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;
import java.io.IOException;
@WebServlet("/scdd2")
public class ServletContextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取ServletContext对象
ServletContext servletContext = request.getServletContext();
System.out.println("ServletContextDemo2中获取key1的值:"+servletContext.getAttribute("key1"));
}
}
特点:
1.唯一性,一个应用程序对应一个ServletContext对象
2.一直存在,只要服务器不关闭,ServletContext对象就一致存在
3.读取web.xml中标签的值【context-param】
HttpServletRequest类和HttpServletResponse类
HttpServletRequest类有什么作用
每次只要有请求进入到Tomcat服务器中,tomcat服务器就会把请求过来的HTTP协议解析好封装到Request对象中,然后传递到service方法(doGet和doPost)中给我们使用,我么可以通过HttpServletRequest对象,获取到请求的信息
常用方法
getRequestURL() //获取统一支援定位符(绝对路径)
/*
在IDEA中,使用localhost访问时,得到的客户端ip地址是 ===》 127.0.0.1
在IDEA中,使用127.0.0.1访问时,得到的客户端ip地址是 ===》 127.0.0.1
在IDEA中,使用 真是IP地址 访问时,得到的客户端ip地址是 ===》 真是IP地址
*/
getRemoteHost()//获取IP地址
getHeader()//获取请求头信息,参数是请求头中key名字 --》 例如User-Agent
*核心*
getParameter() //获取post或get传递传递参数值
getParameterValues() //获取post或get传递传递参数值 【多个值的时候(复选框)】
getMethod()//获取请求方式
setAttribute(key,value) //设置域数据
getAttribute(key) //获取域中值
getRequestDispatcher() //请求转换
HttpServletResponse类可以做什么
主要作用就是将响应信息返回给客户端
常用方法
setContentType()//设置编码集
sendRedirect()//重定向
getWriter()// 获取字符输出流,常用语回传字符串
getOutputStream()//获取字节输出流,常用于下载
web中相对和绝对路径和(/)的意义
相对和绝对路径
/*
在Javaweb中,路径分为两种相对和绝对
相对路径是:
. 表示当前目录
.. 表示上一级目录
获取资源 ./资源名 ../资源名
绝对路径:
http://ip:port/工程名字/资源路径
*/
web中/的不同意义
/*
在web中 / 是一种绝对路径
/ 如果被浏览器解析,就会得到地址为: http://ip:port/
*/
扩展:base标签
1.修改index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
这是web目录下index.html页面<br/>
<a href="/Java2002_web_servlet02/a/b/c.html">c.html</a>
</body>
</html>
2.创建文件夹a和b和从.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
这是a下的b下的c.html页面<br/>
<a href="../../index.html">跳回首页</a>
</body>
</html>
3.启动服务器,可以发现可以正常跳转
4.使用Servelt进行请求转发条件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
这是web目录下index.html页面<br/>
<a href="/Java2002_web_servlet02/a/b/c.html">c.html</a>
<a href="/Java2002_web_servlet02/fwc">Servlet跳转c.html</a>
</body>
</html>
package com.qfedu.BaseLable;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/fwc")
public class ForwardC extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
}
}
5.发现无法正常回到主页,在c.html文件中添加base标签就可以正常跳转了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
base标签只能写在title标签的下面
base标签设置页面路径 是参考href属性地址
-->
<base href="http://localhost:8080/Java2002_web_servlet02/">
</head>
<body>
这是a下的b下的c.html页面<br/>
<!--这里就相当于是写死了路径http://localhost:8080/Java2002_web_servlet02/index.html -->
<a href="index.html">跳回首页</a>
</body>
</html>