Servlet
1 ServletContext
共享数据
ServletContext servletContext = this.getServletContext();
String username = "henry";
servletContext.setAttribute("username",username);
ServletContext servletContext = this.getServletContext();
String s= (String) servletContext.getAttribute("username");
转发请求
ServletContext servletContext = this.getServletContext();
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/hello");
requestDispatcher.forward(req,resp);
获取初始化参数
<context-param>
<param-name>url</param-name>
<param-value>localhost:8080/henry</param-value>
</context-param>
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
获取资源文件
<!-- Maven 在pom.xml的build中配置resources,来防止我们资源导出失败的问题 -->
<build>
<resources>
<resource>
<!-- 设定主资源目录 -->
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
properties文件都被打包到classes路径下,俗称:classpath路径
InputStream inputStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/learn/hello/aa.properties"); //运行时当前目录下
Properties properties = new Properties();
properties.load(inputStream);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().println(username+":"+password);
2 HttpServletResponse
- 继承自ServletResponse
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
- 设置响应头信息的一些方法
void sendError(int var1, String var2) throws IOException;
void sendError(int var1) throws IOException;
void sendRedirect(String var1) throws IOException;
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);
- 状态码
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
应用:下载文件
//String realPath = this.getServletContext().getRealPath("/三座大山.png");
//D:\Tomcat 9.0\webapps\servlet02_war\三座大山.png (系统找不到指定的文件。)
String realPath = "D:\\IDEAworkspace\\JavaWeb\\servlet02\\target\\servlet02\\WEB-INF\\classes\\三座大山.png";
System.out.println("路径: "+realPath);
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
FileInputStream inputStream = new FileInputStream(realPath);
int len=0;
byte[] bytes = new byte[1024];
ServletOutputStream outputStream = resp.getOutputStream();
resp.setHeader("Content-Disposition", "attachment; " +
"filename="+URLEncoder.encode(fileName,"utf-8"));
while((len=inputStream.read(bytes))>0)
{
outputStream.write(bytes,0,len);
}
inputStream.close();
outputStream.close();
图片验证码demo
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//5s自动刷新
resp.setHeader("refresh","5");
resp.setContentType("image/png");
//浏览器不缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Pragma","no-cache");
resp.setHeader("Cache-Control","no-cache");
//创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_BGR);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();
//设置图片背景颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.blue);
g.setFont(new Font(null,Font.BOLD,20));
标题
//x,y文字左下角的坐标
g.drawString(makeString(),0,20);
//图片写给浏览器
ImageIO.write(image,"png",resp.getOutputStream());
}
String makeString()
{
Random random = new Random();
String i = random.nextInt(9999999)+"";
for(int j=0;j<7-i.length();j++)
{
i+="0";
}
return i;
}
实现重定向
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/servlet02_war/verify");//重定向需要从端口号开始的路径
}
重定向和转发的区别:
相同点:
- 页面都会实现跳转
不同点:
- 重定向URL会发生改变,302
- 请求转发URL不会发生改变,307
3 HttpServletRequest
获取前端传递参数,并实现请求转发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KR8FQib9-1625054437963)(C:\Users\henry\AppData\Roaming\Typora\typora-user-images\image-20210630165512512.png)]
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
String s = Arrays.toString(hobby);
System.out.println("+++++++++++++++++++++++++++++");
System.out.println(s);
System.out.println(username);
System.out.println(password);
System.out.println("+++++++++++++++++++++++++++++");
//请求转发
//这里 / 代表当前web应用 注意请求转发和充电向路径不同,直接从当前web应用出发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
Session & Cookie保存会话的两种技术
cookie:
- 客户端技术(响应,请求)
session:
- 服务器技术
1 cookie
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRKaMxXz-1625058428472)(C:\Users\henry\AppData\Roaming\Typora\typora-user-images\image-20210630205834026.png)]
- 从请求中拿到cookie
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //从请求中获得cookie
cookie.getName();//获得cookie的key值
cookie.getValue();//获得cookie的value值
new Cookie("visitTime",System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端
cookie:一般会保存在本地的用户目录下appdata
一个网站cookie是否存在上限!聊聊细节问题。
- 一个Cookie只能保存一个信息;
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
- Cookie大小有限制4kb;
- 300个cookie浏览器上限
删除Cookie;
- 不设置有效期,关闭浏览器,自动失效;
- 设置有效期时间为0;
编码解码:
URLEncoder.encode("秦疆", "utf-8")
URLDecoder.decode(cookie.getvalue(),"UTF-8")
2 Session(重点)
什么是Session:
- 服务器会给每一个用户(浏览器)创建一个Seesion对象;
- 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
- 用户登录之后,整个网站它都可以访问!
使用场景:
- 保存一个登录用户的信息;
- 购物车信息;
- 在整个网站中经常会使用的数据,我们将它保存在Session中;
HttpSession session = req.getSession();
if(session.isNew()) //创建之后必须立刻判断,某些操作使isNew为false
{
writer.write("this is a new session");
}
else
{
session.setAttribute("name","henrydai");
writer.write("old session,created at "+session.getCreationTime());
writer.write(" id is "+session.getId());
session.invalidate(); //手动失效
}
HttpSession session = req.getSession();
String name = (String) session.getAttribute("name");
<session-config>
<!--在web.xml中设置session有效时间,以分钟为单位-->
<session-timeout>12</session-timeout>
</session-config>
Session和Cookie的区别:
- ·Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费).
- Session对象由服务创建;