1.1创建web项目:
生成目录如下:
在web目录下的WEB-INF下创建classes目录和lib目录如下:
运行项目,出现以下页面,则表示web项目创建成功:
1.2改变maven默认位置如下:
1.3如果导入HttpServlet报错如下,Cannot resolve symbol ‘HttpServlet’:
可以先在idea项目内创建一个libs目录,然后是从Tomcat的安装目录的lib目录下,将servlet-api.jar 复制到到libs目录下,同时将servlet-api.jar 添加到当前项目中
Tomcat的安装目录lib目录下的servlet-api.jar位置如下:
把复制的servlet-api.jar放在libs目录下如图:
将servlet-api.jar 添加到当前项目中如图:
右键servlet-api.jar
成功如下:
2.1在以下添加java代码和jsp代码,然后运行项目
package cn.cyj.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
@WebServlet("/hello")
public class App extends HttpServlet{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("hello maven web");
}
}
jsp:
<html>
<body>
<h2>Hello World!</h2>
<a href="hello">aa</a>
</body>
</html>
可以看到如图所示结果:
Shared libraries(共享库)/runtimes pluggability(运行时插件能力)
1.Servlet容器启动会扫描,当前应用里面的每一个jar包的ServletContainerInitializer的实现
2.提供ServletContainerInitializer的实现类,必须绑定在META-INF/services/javax.servlet.ServletContainerInitializer文件的内容就是ServletContainerInitializer实现类的全类名
总结:容器在启动应用的时候,会扫描当前应用每一个jar包里面
META-INF/services/javax.servlet.ServletContainerInitializer指定的实现类,启动并运行这个实现类的方法,传入感兴趣都类型
ServletContainerInitializer @HandlesTypes
3.1创建一个ServletContainerInitializer实现类MyServletContainerInitializer:
package cn.cyj.servlet;
import cn.cyj.service.HelloService;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import java.util.Set;
//@HandlesTypes 容器启动的时候会将@HandlesTypes指定的value类型下面的子类(实现类,子接口等)传递过来
//传入感兴趣的类型HelloService.class
@HandlesTypes(value = {HelloService.class})
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* 应用启动的时候,会运行onStartup这个方法
* @param set Set<Class<?>> set:感兴趣类型的所有子类型
* @param servletContext ServletContext servletContext:servlet上下文
* 代表当前web应用的ServletContext,一个web应用一个ServletContext
* @throws ServletException
*/
public void onStartup(Set<Class<?>> set, ServletContext servletContext)
throws ServletException {
System.out.println("感兴趣的类型:");
for (Class<?> cla : set){
System.out.println(cla);
}
}
}
3.2把ServletContainerInitializer实现类MyServletContainerInitializer的全类名配在指定目录resources\META-INF\services\javax.servlet.ServletContainerInitializer下,如图:
cn.cyj.servlet.MyServletContainerInitializer
3.3创建感兴趣类和其子类,子接口等如下:
HelloService接口:
package cn.cyj.service;
public interface HelloService {
}
实现HelloService接口的抽象类AbstractHelloService:
package cn.cyj.service;
public abstract class AbstractHelloService implements HelloService{
}
实现HelloService接口的实现类HelloServiceImpl:
package cn.cyj.service;
public class HelloServiceImpl implements HelloService{
}
继承HelloService的接口HellowServiceExt:
package cn.cyj.service;
public interface HellowServiceExt extends HelloService{
}
3.4启动项目,控制台可以看到如下:
package cn.cyj.servlet;
import cn.cyj.service.HelloService;
import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import java.util.EnumSet;
import java.util.Set;
//@HandlesTypes 容器启动的时候会将@HandlesTypes指定的value类型下面的子类(实现类,子接口等)传递过来
//传入感兴趣的类型HelloService.class
@HandlesTypes(value = {HelloService.class})
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* 应用启动的时候,会运行onStartup这个方法
* @param set Set<Class<?>> set:感兴趣类型的所有子类型
* @param servletContext ServletContext servletContext:servlet上下文
* 代表当前web应用的ServletContext,一个web应用一个ServletContext
* @throws ServletException
*
*
* 1.使用ServletContext注册Web组件(Servlet,Filter,Listener)
* 2.使用编码的方式,在项目启动的时候给ServletContext里面添加组件,必须在项目启动的时候添加
* 方法:
* 1.在ServletContainerInitializer实现类得到的servletContex添加组件
* 2.在ServletContextListener得到的的servletContex添加组件
*/
public void onStartup(Set<Class<?>> set, ServletContext servletContext)
throws ServletException {
System.out.println("感兴趣的类型:");
for (Class<?> cla : set){
System.out.println(cla);
}
//注册组件 Servlet
ServletRegistration.Dynamic servlet = servletContext.addServlet("userServlet",new UserServlet()); //userServlet是名字
//配置servlet的映射信息
servlet.addMapping("/user");
//注册Listener
servletContext.addListener(UserListener.class);
//注册Filter
FilterRegistration.Dynamic filter = servletContext.addFilter("userFilter",new UserFilter());
//添加映射信息
filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),true,"/*"); //拦截所有请求信息
}
}
UserServlet组件:
package cn.cyj.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//给浏览器响应一个用户名字
resp.getWriter().write("tomcat。。。");
}
}
UserFilter组件:
package cn.cyj.servlet;
import javax.servlet.*;
import java.io.IOException;
public class UserFilter implements Filter {
/**
* 初始化方法
* @param filterConfig
* @throws ServletException
*/
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 用于过滤请求
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("UserFilter...doFilter....");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
/**
* 销毁方法
*/
public void destroy() {
}
}
UserListener组件:
package cn.cyj.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class UserListener implements ServletContextListener {
/**
* 监听ServletContext 服务器启动初始化
* @param servletContextEvent
*/
public void contextInitialized(ServletContextEvent servletContextEvent) {
//获取servletContex添加组件
ServletContext servletContext = servletContextEvent.getServletContext();
System.out.println("UserListener...contextInitialized...");
}
/**
* 监听ServletContext 服务器销毁
* @param servletContextEvent
*/
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("UserListener...contextDestroyed...");
}
}
package cn.cyj.study;
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("/servletLive")
public class ServletLive extends HttpServlet {
/**
* 初始化方法
* 系统方法,服务器自动调用
* 当请求到达Servlet容器时,Servlet容器会判断该Servlet对象是否存在,如果不存在,则创建实例并初始化
* 方法只会执行一次
* @throws ServletException
*/
@Override
public void init() throws ServletException {
System.out.println("Servlet被创建了。。。");
}
/**
* 就绪、服务方法(处理请求数据)
* 系统方法,服务器自动调用
* 当有请求到达Servlet时,就会调用该方法
* 方法可多次被调用
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet被调用了。。。");
}
/**
* 销毁方法
* 系统方法,服务器自动调用
* 当服务器关闭或应用程序停止时,调用该方法
* 方法只会执行一次
*/
@Override
public void destroy(){
System.out.println("Servlet被销毁了。。。");
}
}
每次访问链接都会执行一次service方法,项目刚启动时执行一次init方法,项目关闭执行一次destroy方法,init方法和destroy方法只会执行一次。
package cn.cyj.study;
import javax.jws.WebService;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 实现Servlet
* 1.创建普通java类
* 2.实现Servlet超类,继承HttpServlet类
* 3.重写servlet方法,用来处理请求
* 4.设置注解,指定访问的路径
*/
/**
* @WebServlet 路径中的‘/'不要忘记写,否则访问不到。
* name表示名字,一般不用设置,value,urlPatterns表示访问该类的路径,可以用数组表示多个访问路径
*
* @WebServlet(name = "MyServlet",value = {"/hello01","/hello02"})
* 等价于 @WebServlet(name = "MyServlet",urlPatterns = {"/hello01","/hello02"})
* */
@WebServlet("/hello01")
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
//打印内容在控制台
System.out.println("myServlet...");
//通过流输出数据到浏览器
response.getWriter().write("myServlet...");
/**
* HttpServletRequest常用方法:
*/
//获取请求时的完整路径(从http开始,到?前面结束)
String url = request.getRequestURL()+"";
System.out.println("完整路径:"+url);
//获取请求的部分路径(从项目的站点名开始,到?前面结束)
String url1 = request.getRequestURI();
System.out.println("部分路径:"+url1);
//获取请求时的参数字符串(从?后面开始,到最后的字符串)
String queryString = request.getQueryString();
System.out.println("参数字符串"+queryString);
//获取请求方式(GET和POST)
String method = request.getMethod();
System.out.println("请求方式:"+method);
//获取当前协议版本(HTTP/1.1)
String prototal = request.getPathInfo();
System.out.println("当前协议:"+prototal);
//获取项目的站点名(项目对外访问路径)
String webapp = request.getContextPath();//上下文路径
System.out.println("项目站点名"+webapp);
/**
* 获取请求参数
*/
//获取指定名称的参数值(重点!!!)
String username = request.getParameter("username"); //后面的username必须和访问链接的参数一样,下面的password,hobby同理。
String password = request.getParameter("password");
System.out.println("username:"+username+"password:"+password);
//获取指定名称的参数的所有参数值(用于复选框传值)
String[] hobby = request.getParameterValues("hobby");
//判断数组是否为空
if (hobby != null && hobby.length > 0){
for (String oneHobby : hobby){
System.out.println("爱好:"+oneHobby);
}
}
}
}
访问连接如下:
打印结果如下:
1.Get请求(不会乱码):
package cn.cyj.study;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 请求乱码问题
*
* tomcat 8.5
* GET请求 不会乱码
*/
@WebServlet("/servlet01")
public class ServletMa extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//获取客户端传递过来的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username);
System.out.println("password:"+password);
}
}
请求链接:
打印结果:
2.POST请求(会乱码):
<%--
Created by IntelliJ IDEA.
User: AUAS
Date: 2022/8/13
Time: 14:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form method="post" action="servlet02">
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<button>登录</button>
</form>
</body>
</html>
package cn.cyj.study;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
/**
* 请求乱码问题
* 乱码原因:
* 由于在解析过程中默认使用的编码方式为ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。
*
* tomcat 8.5
* GET请求 不会乱码
* POST请求 会乱码,通过设置服务器解析编码的格式 request.setCharacterEncoding("UTF-8");
* 必须把设置编码写在获取客户端传递过来的参数前,且request.setCharacterEncoding("UTF-8")只对post请求有效
*
* tomcat7及以下Get请求也乱码时:
* String username1 = new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");对所有请求方法有效
* 使用上面方法获取客户端传递过来的参数,就可以解决乱码问题,但是,如果本来是没有乱码的,使用该方法获取参数,会让参数变乱码,
* 所以不要随便使用该方法。只在tomcat7及以下Get请求使用。
*
*/
@WebServlet("/servlet02")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//设置服务器解析编码的格式
request.setCharacterEncoding("UTF-8");
//获取客户端传递过来的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:"+username);
System.out.println("password:"+password);
//
String username1 =
new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
}
}
请求链接:
填写后登录就可以把参数发送到上面的servlet02上,检测post的乱码问题
没有以下代码时乱码,有时不乱码,如下两图:
//设置服务器解析编码的格式
request.setCharacterEncoding("UTF-8");
package cn.cyj.study;
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.UnsupportedEncodingException;
/**
* 请求转发跳转
* request.getRequestDispatcher("servlet04").forward(request,response);
* 可以让请求从服务器跳转到客户端(或跳转到指定Servlet)
* 特点:
* 1.服务端行为
* 2.地址栏不发生改变
* 3.从始至终只有一个请求
* 4.数据可以共享
*/
@WebServlet("/servlet03")
public class Servlet03 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//接收客户端请求参数
String username = request.getParameter("username");
System.out.println("servlet03 username: "+username);
//请求转发跳转到Servlet04
//request.getRequestDispatcher("servlet04").forward(request,response);
//请求转发跳转到jsp页面
//request.getRequestDispatcher("login.html").forward(request,response);
request.getRequestDispatcher("login.jsp").forward(request,response);
}
}
package cn.cyj.study;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
/**
* 请求转发跳转
* 可以让请求从服务器跳转到客户端(或跳转到指定Servlet)
* 服务器行为
*/
@WebServlet("/servlet04")
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//接收客户端请求参数
String username = request.getParameter("username");
System.out.println("Servlet04 username: "+username);
}
}
<%--
Created by IntelliJ IDEA.
User: AUAS
Date: 2022/8/13
Time: 14:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form method="post" action="servlet02">
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<button>登录</button>
</form>
</body>
</html>
请求转发跳转到Servlet04代码结果如下:
//请求转发跳转到Servlet04
request.getRequestDispatcher("servlet04").forward(request,response);
请求转发跳转到jsp页面(html页面)代码结果如下:
//请求转发跳转到jsp页面
//request.getRequestDispatcher("login.html").forward(request,response);
request.getRequestDispatcher("login.jsp").forward(request,response);
package cn.cyj.study;
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.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
* request作用域
* 通过该对象可以在一个请求中传递数据,作用范围;在一次请求中有效,即服务器跳转有效(请求转发跳转时也是一次请求,所以也有效)
* 设置域对象内容
* request.setAttribute("name","admin");
* 获取域对象内容
* request.getAttribute("name")
* 删除域对象内容
* request.removeAttribute("name");
*/
@WebServlet("/servlet05")
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.out.println("Servlet05。。。");
//设置域对象内容
request.setAttribute("name","admin");
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
request.setAttribute("list",list);
//请求转发跳转到Servlet04
request.getRequestDispatcher("servlet06").forward(request,response);
//请求转发跳转到jsp页面
//request.getRequestDispatcher("login.html").forward(request,response);
//request.getRequestDispatcher("login.jsp").forward(request,response);
}
}
package cn.cyj.study;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
* request作用域
* 通过该对象可以在一个请求中传递数据,作用范围;在一次请求中有效,即服务器跳转有效(请求转发跳转时也是一次请求,所以也有效)
* 设置域对象内容
* request.setAttribute("name","admin");
* 获取域对象内容
* request.getAttribute("name")
* 删除域对象内容
* request.removeAttribute("name");
*/
@WebServlet("/servlet06")
public class Servlet06 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
System.out.println("Servlet06。。。");
//获取域对象内容
String name = (String)request.getAttribute("name"); //后面的name必须是设置域对象的名字
System.out.println("name:"+name);
List<String> list = (List<String>)request.getAttribute("list");
System.out.println("list:"+list.get(0));
}
}
在Servlet05类创建域对象,Servlet06获取域对象,因为Servlet05通过了请求转发发送到Servlet06,所以数据共享,属于一次请求,所以Servlet06可以获取到域对象。如果Servlet05没有请求转发,Servlet06将无法获取到以下的数据,因为不是同一个请求。
package cn.cyj.study;
import javax.servlet.ServletOutputStream;
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;
/**
* HttpServletResponse响应数据
* 字符输出流(输出字符串)
* 字节输出流(输出一切数据)
*
* 上面两种流不能同时使用,否则会报错
* */
@WebServlet("/response01")
public class Response01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
/**
* 字符输出流(输出字符串)
*/
// //获取字符输出流
// PrintWriter writer = response.getWriter();
// //输出数据
// writer.write("PrintWriter");
/**
* 字节输出流(输出一切数据)
*/
//获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
//输出数据
outputStream.write("ServletOutputStream".getBytes());
}
}
结果如下:
1.字符流乱码问题:
package cn.cyj.study;
import javax.servlet.ServletOutputStream;
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;
/**
* 字符流响应数据乱码问题
* 乱码原因:
* 对于getWriter()获取到的字符流,响应中文一定会出现乱码,
* 因为服务器端在进行编码时默认会使用ISO-8859-1格式的编码,该编码方式不支持中文
*
* 乱码解决:
* 方法一:
* 1.设置服务端的编码格式
* response.setCharacterEncoding("UTF-8");
* 2.设置客户端的编码格式
* response.setHeader("content-type","text/html;charset=UTF-8");
* 总结:必须设置客户端和服务端的编码都支持中文,而且客户端和服务端保持编码一致
* 方法二:
* 1.同时设置客户端和服务端的编码格式
* response.setContentType("text/html;charset=UTF-8");
*
*
*/
@WebServlet("/response02")
public class Response02 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// //设置服务端的编码格式
// response.setCharacterEncoding("UTF-8");
// //设置客户端的编码格式
// response.setHeader("content-type","text/html;charset=UTF-8");
//同时设置客户端和服务端的编码格式
response.setContentType("text/html;charset=UTF-8");
/**
* 字符输出流(输出字符串)
*/
//获取字符输出流
PrintWriter writer = response.getWriter();
//输出数据
writer.write("字符流
");
}
}
2.字节流乱码问题:
package cn.cyj.study;
import javax.servlet.ServletOutputStream;
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;
/**
* 字节流响应数据乱码问题
* 乱码原因:
* 对于getOutputStream()获取到的字符流,响应中文一定会出现乱码,
* 因为服务器端在进行编码时默认会使用ISO-8859-1格式的编码,该编码方式不支持中文
*
* 乱码解决:
* 方法一:
* 1.设置服务端的编码格式
* response.setCharacterEncoding("UTF-8");
* 2.设置客户端的编码格式
* response.setHeader("content-type","text/html;charset=UTF-8");
* 总结:必须设置客户端和服务端的编码都支持中文,而且客户端和服务端保持编码一致
* 方法二:
* 1.同时设置客户端和服务端的编码格式
*/
@WebServlet("/response03")
public class Response03 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// //设置服务端的编码格式
// response.setCharacterEncoding("UTF-8");
// //设置客户端的编码格式
// response.setHeader("content-type","text/html;charset=UTF-8");
//同时设置客户端和服务端的编码格式
response.setContentType("text/html;charset=UTF-8");
/**
* 字节输出流(输出一切数据)
*/
//获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
//输出数据
outputStream.write("字节流
".getBytes("UTF-8"));
}
}
package cn.cyj.study;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 重定向
* 服务器指导,客户端行为
* 存在两次请求,地址栏会发生改变
* request对象不共享
*/
@WebServlet("/response04")
public class Response04 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("response04....");
//重定向跳转到response05
response.sendRedirect("response05");
}
}
package cn.cyj.study;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 重定向
* 服务器指导,客户端行为
* 存在两次请求,地址栏会发生改变
* request对象不共享
*/
@WebServlet("/response05")
public class Response05 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("response05....");
}
}
请求转发(request.getRequestDispatcher(“servlet04”).forward(request,response);) | 重定向(response.sendRedirect(“response05”);) |
---|---|
一次请求,request域中数据共享 | 两次请求,request域中数据不共享 |
服务器端行为 | 客户端行为 |
地址栏不发生改变 | 地址栏发生改变 |
转发的地址必须是本项目的地址(当前域名的资源) | 重定向的地址可以是任何地址,包含百度地址等等 |
package cn.cyj.study.mycookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie的创建和发送
*/
@WebServlet("/cookie01")
public class Cookie01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//Cookie的创建
Cookie cookie = new Cookie("username","admin");
//发送(响应)Cookie对象
response.addCookie(cookie);
}
}
package cn.cyj.study.mycookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie的获取
* 返回的是Cookie数组
*/
@WebServlet("/cookie02")
public class Cookie02 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//获取cookie数组
Cookie[] cookies = request.getCookies();
//判断cookie是否为空
if (cookies != null && cookies.length > 0){
//遍历cookie数组
for (Cookie cookie : cookies){
//获取cookie的值
String name = cookie.getName();
String value = cookie.getValue();
System.out.println("cookie的名称:"+name+" 值:"+value);
}
}
}
}
package cn.cyj.study.mycookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie的到期时间
* 负整数:
* 默认值-1,表示只在浏览器内存中存活,关闭浏览器失效
* 正整数:
* 表示存活指定秒数,会将数据存在磁盘中,单位秒
* 零:
* 表示删除cookie(原来有这个cookie就删除)
*/
@WebServlet("/cookie03")
public class Cookie03 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//到期时间:负整数(默认值-1,表示只在浏览器内存中存活,关闭浏览器失效)
Cookie cookie = new Cookie("username","admin");
cookie.setMaxAge(-1);//关闭浏览器失效
response.addCookie(cookie);
//到期时间:正整数(表示存活指定秒数,会将数据存在磁盘中)
Cookie cookie2 = new Cookie("username2","admin2");
cookie2.setMaxAge(20);//存活20秒
response.addCookie(cookie2);
//到期时间:零(表示删除cookie)
Cookie cookie3 = new Cookie("username3","admin3");
cookie3.setMaxAge(0);//删除cookie
response.addCookie(cookie3);
}
}
package cn.cyj.study.mycookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Cookie的注意点
* 1.Cookie只在当前浏览器中有效(不同浏览器或者电脑存在的cookie不是共用的)
* 2.Cookie不能存中文
* 如果一定要存中文,则需要通过URLEncoder.encode()方法进行编码,获取时通过URLDecoder.decode()方法进行解码
* 3.如果出现同名的Cookie对象,则会覆盖
* 4.Cookie的存储数量是有上限的,不同浏览器的上限不同。每个Cookie存储的大小是有限的,在4kb左右
*/
@WebServlet("/cookie04")
public class Cookie04 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//Cookie存中文
String name = "姓名";
String value = "张三";
//将中文通过进行编码
name = URLEncoder.encode(name);
value = URLEncoder.encode(value);
//创建Cookie对象
Cookie cookie = new Cookie(name,value);
//响应Cookie
response.addCookie(cookie);
//获取Cookie时,通过进行解码
Cookie[] cookies = request.getCookies();
//判断非空
if (cookies != null && cookies.length > 0){
//遍历
for(Cookie cookie1 : cookies){
//解码
System.out.println(URLDecoder.decode(cookie1.getName()));
System.out.println(URLDecoder.decode(cookie1.getValue()));
}
}
//cookie值覆盖
Cookie cookie2 = new Cookie("username","admin");
response.addCookie(cookie2);
//将原来已有的Cookie对象重新设置
Cookie cookie3 = new Cookie("username","admin1");
response.addCookie(cookie3);
}
}
package cn.cyj.study.mycookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Cookie的路径
* 1.当前服务器下任何项目的任意资源都可获取Cookie对象
* 设置路径为"/",表示在当前服务器下任何项目都可以访问到Cookie对象
* 2.当前项目下的资源可获取Cookie对象(默认)
* 可不设置Cookie的path 或 设置为当前站点名
* 3.指定项目下的资源可获取Cookie对象
* 4.指定目录下的资源可获取Cookie对象
*
* 总结:只有访问的路径中包含Cookie对象的path值,才可以获取到cookie对象
*
*/
@WebServlet("/cookie05")
public class Cookie05 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
/**
* 当前服务器下任何项目的任意资源都可获取Cookie对象
*/
Cookie cookie1 = new Cookie("cookie1","cookie1");
//设置路径为"/",表示在当前服务器下任何项目都可以访问到Cookie对象
cookie1.setPath("/");
//响应Cookie
response.addCookie(cookie1);
/**
* 当前项目下的资源可获取Cookie对象,可不设置会直接默认(默认)
*/
Cookie cookie2 = new Cookie("cookie2","cookie2");
//设置路径为"/",表示在当前服务器下任何项目都可以访问到Cookie对象
cookie2.setPath("/spring_servlet_day03_war_exploded");
//响应Cookie
response.addCookie(cookie2);
/**
* 指定项目下的资源可获取Cookie对象
*/
Cookie cookie3 = new Cookie("cookie3","cookie3");
//设置指定项目的站点名
cookie3.setPath("/spring_servlet_day02_war_exploded");
//响应Cookie
response.addCookie(cookie3);
/**
* 指定目录下的资源可获取Cookie对象
*/
Cookie cookie4 = new Cookie("cookie4","cookie4");
//设置指定项目的站点名
cookie4.setPath("/spring_servlet_day03_war_exploded/cookie02");
//响应Cookie
response.addCookie(cookie4);
}
}
package cn.cyj.study.Mysession;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Session对象的获取
* request.getSession()
* 当获取Session对象时,会先判断session对象是否存在,
* 如果存在就获取session对象,如果不存在就创建session对象
*
* 常用方法
* 获取session的会话标识符 getId()
* 获取session的创建时间 getCreationTime()
* 获取session最后一次访问时间 getLastAccessedTime()
* 判断是否是新的session对象 isNew()
*
*/
@WebServlet("/session01")
public class Session01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//获取session对象
HttpSession session = request.getSession();
//获取session的会话标识符
String id = session.getId();
System.out.println(id);
//获取session的创建时间
Long time = session.getCreationTime();
System.out.println(time);
//获取session最后一次访问时间
Long time1 = session.getLastAccessedTime();
System.out.println(time1);
//判断是否是新的session对象
Boolean isNew = session.isNew();
System.out.println(isNew);
}
}
session和cookie关联:
package cn.cyj.study.Mysession;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Session域对象
* getSession() 获取域对象
* setAttribute() 设置域对象
* removeAttribute() 移除域对象
*
* 请求转发
* 一次请求
* request作用域有效
* session作用域有效
* 重定向
* 两次请求
* request作用域无效
* session作用域有效
*/
@WebServlet("/session02")
public class Session02 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
/**
* Session域对象
*/
//获取session对象
HttpSession session = request.getSession();
//设置域对象
session.setAttribute("username","admin");
session.setAttribute("password",111);
//移除域对象
session.removeAttribute("password");
/**
* request域对象
*/
//设置域对象
request.setAttribute("name","admin1");
/**
* 请求转发到jsp页面
*/
// request.getRequestDispatcher("session.jsp").forward(request,response);
/**
* 重定向跳转到jsp页面
*/
response.sendRedirect("session.jsp");
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取域对象</title>
</head>
<body>
<%
//获取session域对象
String username = (String)request.getSession().getAttribute("username");
String password = (String)request.getSession().getAttribute("password");
//获取request对象
String name = (String)request.getAttribute("name");
System.out.println("username:"+username+",password:"+password+",name:"+name);
%>
</body>
</html>
package cn.cyj.study.Mysession;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Session对象的销毁
* 1.默认到期时间
* Tomcat中Session默认的存活时间为30分钟,即你不操作界面的时间,一旦有操作,session会重新计时
* 默认的存活时间可以在Tomcat中的conf目录下的web.xml文件中进行修改
* <!-- session 默认的最大不活动时间(即存活时间),单位:分钟 -->
* <session-config>
* <session-timeout>30</session-timeout>
* </session-config>
* 2.手动设置到期时间
* 可以在程序中自己设定session的生命周期,
* 通过session.setMaxInactiveInterval(int)来设定session的最大不活动时间(即存活时间),单位:秒
* 可以通过getMaxInactiveInterval()方法来查看当前Session对象的最大不活动时间
* 3.立即销毁
* 可以通过session.invalidate()方法让session立即失效
* 4.关闭浏览器失效(不用代码编写,只要cookie失效,session就会重新创建一个,因为session和cookie的对应不上)
* session底层依赖cookie,cookie对象默认只在浏览器内存中存活,关闭浏览器即失效
* 5.关闭服务器(不用代码编写,因为关闭服务器,服务器的所有session都被销毁,所以session和cookie也不一致,session也会重新创建。)
* 当关闭当前服务器时,session销毁
*
*/
@WebServlet("/session03")
public class Session03 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
/**
* Session域对象
*/
//获取session对象
HttpSession session = request.getSession();
//设置域对象
session.setAttribute("username","admin");
//获取Session对象的最大活动时间
// Integer time = session.getMaxInactiveInterval();
// System.out.println(time);
//
// //修改session最大不活动时间
// session.setMaxInactiveInterval(15);//15秒失效
//立即销毁,可以通过session.invalidate()方法让session立即失效
session.invalidate();
}
}
package cn.cyj.study.Myservletcontext;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 获取ServletContext对象
* 1.通过request对象获取
* ServletContext servletContext1 = request.getServletContext();
* 2.通过session对象获取
* ServletContext servletContext2 = request.getSession().getServletContext();
* 3.通过servletConfig对象获取
* ServletContext servletContext3 = getServletConfig().getServletContext();
* 4.直接获取
* ServletContext servletContext4 = getServletContext();
*
* 常用方法:
* 1.获取当前服务器的版本信息
* String serverInfo = request.getServletContext().getServerInfo();
* 2.获取项目的真实路径
* String realPath = request.getServletContext().getRealPath("/");
*/
@WebServlet("/sc01")
public class ServletContext01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response){
//通过request对象获取
ServletContext servletContext1 = request.getServletContext();
//通过session对象获取
ServletContext servletContext2 = request.getSession().getServletContext();
//通过servletConfig对象获取
ServletContext servletContext3 = getServletConfig().getServletContext();
//直接获取
ServletContext servletContext4 = getServletContext();
//常用方法
//1.获取当前服务器的版本信息
String serverInfo = request.getServletContext().getServerInfo();
System.out.println("获取当前服务器的版本信息:"+serverInfo);
//2.获取项目的真实路径
String realPath = request.getServletContext().getRealPath("/");
System.out.println("获取项目的真实路径:"+realPath);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<!-- 文件上传-->
<!-- 1.准备表单-->
<!-- 2.设置表单的提交类型为POST请求,method="post"-->
<!-- 3.设置表单类型为文件上传表单 enctype="multipart/form-data"-->
<!-- 4.设置文件提交的地址-->
<!-- 5.准备表单元素-->
<!-- 1.普通的表单项 type='text'-->
<!-- 2.文件项 type="file"-->
<!-- 6.设置表单元素的name属性值(表单提交一定要设置表单元素的name属性值,否则后台无法接收数据)-->
<form method="post" enctype="multipart/form-data" action="uploadServlet">
姓名:<input type="text" name="username"><br>
文件:<input type="file" name="myfile"><br>
<!-- button默认的类型是提交类型 type="submit" -->
<button>提交</button>
</form>
</body>
</html>
package cn.cyj.study.myupload;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* 文件上传
* 使用注解 @MultipartConfig将一个Servlet标识为支持文件上传
* Servlet将 multipart/form-data 的 POST 请求封装成Part对象,通过Part对上传的文件进行操作
*/
@WebServlet("/uploadServlet")
@MultipartConfig //如果是文件上传,必须要设置该注解!!!
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.out.println("文件上传。。。");
//设置请求的编码格式
request.setCharacterEncoding("UTF-8");
//获取普通表单项(获取参数)
String userName = request.getParameter("username"); //表单中表单元素的username
System.out.println("username:"+userName);
//获取Part对象(Servlet将 multipart/form-data 的 POST 请求封装成Part对象)
Part part = request.getPart("myfile"); //表单中file文件域中的name属性值
//通过Part对象获取得到上传的文件名
String fileName = part.getSubmittedFileName();
System.out.println("上传的文件名:"+fileName);
//得到文件的存放路径
String filePath = request.getServletContext().getRealPath("/");
System.out.println("文件存放的路径:"+filePath);
//上传文件到指定目录
part.write(filePath+"/"+fileName);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>超链接下载文件</title>
</head>
<body>
<!--
超链接下载
当使用超链接(a标签)时,如果遇到浏览器能够识别的资源,则会显示内容,
如果遇到浏览器不能识别的资源,则会进行下载
download属性
通过download规定浏览器进行下载,不管浏览器能不能识别
download属性可以不写任何信息,下载的文件名会自动使用默认的文件名,
如果设置了download属性的值,则使用设置的值作为下载的文件名
-->
<!-- 浏览器能够识别的资源 -->
<a href="download/1.txt">文本文件</a>
<a href="download/2.png">图片文件</a>
<!-- 浏览器不能识别的资源 -->
<a href="download/3.rar">压缩文件</a>
<br>
<a href="download/1.txt" download>文本文件</a>
<a href="download/2.png" download="风景图片.png">图片文件</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台代码 文件下载</title>
</head>
<body>
<form action="downloadServlet">
文件名:<input name="fileName" type="text" placeholder="请输入要下载的文件名">
<button>下载</button>
</form>
</body>
</html>
package cn.cyj.study.myupload;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* 文件下载 后台代码
* 1.需要通过response.setContentType方法设置Content-type头字段的值,
* 浏览器无法使用某种方式或激活某个程序来处理的MIME类型,例如:"application/x-msdownload",
* 或"application/octet-stream"等
* 2.需要通过response.setHeader方法设置Content-Disposition头的值为
* attachment;filename=文件名"
* 3.读取下载文件,调用response.getOutputStream()方法向客户端写入文件内容
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("文件下载。。。");
//设置请求的编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取参数(获取要下载的文件名)
String fileName = request.getParameter("fileName");
//参数前端传过来的文件名的非空判断 trim() 去除字符串前后空格
if(fileName == null || "".equals(fileName.trim())){
response.getWriter().write("请输入要下载的文件名!");
response.getWriter().close();
return;
}
//得到图片存放的路径
String path = request.getServletContext().getRealPath("/download/");
//通过路径得到file对象
File file = new File(path+fileName);
//判断文件对象是否存在,并且是否是一个标准文件
if (file.exists() && file.isFile()){
//设置响应类型(浏览器无法使用某种方式或激活某个程序来处理的MIME类型
response.setContentType("application/x-msdownload");
//设置响应头
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//得到file文件输入流
InputStream in = new FileInputStream(file);
//得到文件输出流
ServletOutputStream out = response.getOutputStream();
//定义byte数组
byte[] bytes = new byte[1024];
//定义长度
int len = 0;
//循环输出
while ((len = in.read(bytes)) != -1){
out.write(bytes,0,len);
}
//关闭资源
out.close();
in.close();
}else {
response.getWriter().write("文件不存在,请重试");
response.getWriter().close();
}
}
}