首页 > 编程语言 >JavaWeb(二)

JavaWeb(二)

时间:2023-01-19 11:35:57浏览次数:44  
标签:http JavaWeb resp public import servlet javax


6、Servlet

6.1、Servlet简介

  • Servlet是sun公司用于开发动态web的一门技术
  • sun公司在这些API中提供的一个叫做Servlet的接口
  • 编写一个类,实现Servlet接口
  • 把开发好的java类部署到web服务器中

把实现了Servlet接口的java程序叫做Servlet

6.2、构建一个Maven项目,HelloServlet

  1. 构建一个普通的Maven项目,并删除里面的src目录,在该目录下新建module即可。整个空的工程就是Maven的主工程
  2. 关于Maven父子工程的理解:
    在父项目中:
<modules>
<module>1_servlet_01</module>
</modules>

在子项目中:

<parent>
<artifactId>16_maven_03</artifactId>
<groupId>per.mobian</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

父项目中的子项目可以使用父项目的已经导入的依赖(类似于继承)

  1. Maven环境优化
  1. 修改web.xml为最新版(在JavaWeb(一)中有)
  2. 将maven的结构搭建完整
  1. 编写一个Servlet程序
  1. 编写一个普通类
  2. 实现一个Servlet接口
package per.mobian.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

PrintWriter writer = resp.getWriter();
writer.print("hello servlet!!!");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);

}

}
  1. 编写Servlet的映射
    我们编写的是java程序,但是需要通过浏览器来进行访问,而浏览器需要连接web服务器,多以我们需要在web服务器中注册我们写的Servlet,即还需要给他一个浏览器能够访问的路径
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

</web-app>
  1. 配置Tomcat服务器
    配置项目发布得路径(将项目放在Tomcat服务器上)
  2. 启动测试

6.3、Servlet原理

Servlet是由web服务器调用,web服务器

JavaWeb(二)_java

6.4、Mapping

  1. 一个路径对应一个映射
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
  1. 一个路径对应多个映射
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
  1. 一个路径对应所有映射
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
  1. 默认请求路径
<!--此用法会将主页的index.jsp覆盖,所以不建议使用-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
  1. 指定一些前缀或者后缀等等。。。
<!--此时访问页面,只需要结尾正确即可-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.helloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.mobian</url-pattern>
</servlet-mapping>

6.优先级问题

指定路径的访问优先级 > /*路径下的默认访问路径

测试情况下,只要不是访问的/hello路径,则自动跳转到404页面

测试代码:

package per.mobian;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class errorTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");

PrintWriter writer = resp.getWriter();
writer.print("<h1>404<h1>");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>errorTest</servlet-name>
<servlet-class>per.mobian.errorTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>errorTest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

6.5、ServletContext

1、共享数据

JavaWeb(二)_ide_02

测试代码:

package per.mobian.servlet;

import javax.servlet.ServletContext;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter(); 初始化参数
// this.getServletConfig(); 获取Servlet配置
// this.getServletContext(); 获取Servlet的上下文
ServletContext context = this.getServletContext();

String name = "默辨";
context.setAttribute("name",name);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package per.mobian.servlet;

import javax.servlet.ServletContext;
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 ContextServletTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String name = (String) context.getAttribute("name");

resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.getWriter().print(name);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>per.mobian.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>


<servlet>
<servlet-name>ContextServletTest</servlet-name>
<servlet-class>per.mobian.servlet.ContextServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServletTest</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>

</web-app>

执行结果:

JavaWeb(二)_ide_03

执行结果分析:第一次请求/context时,name显示内容为null。当执行/hello页面后,会执行其对映映射路径下的类,继而成功的给name赋值,当再次执行到/context页面时,由于显示的内容是中文,所以首先需要设置字符的编码,继而浏览器端能够成功的打印出指定的信息。

2、获取初始化参数

测试代码:

package per.mobian.servlet;

import javax.servlet.ServletContext;
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 ContextServletTest2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

ServletContext context = this.getServletContext();
String contextServletTest2 = context.getInitParameter("ContextServletTest2");
resp.getWriter().print(contextServletTest2);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<servlet>
<servlet-name>ContextServletTest2</servlet-name>
<servlet-class>per.mobian.servlet.ContextServletTest2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServletTest2</servlet-name>
<url-pattern>/context2</url-pattern>
</servlet-mapping>

<context-param>
<param-name>ContextServletTest2</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>

</web-app>

执行结果:

JavaWeb(二)_xml_04

3、请求转发

测试代码:

package per.mobian.servlet;

import javax.servlet.ServletContext;
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 ContextServletTest3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取上下文
ServletContext context = this.getServletContext();
//先获取转发的请求路径,再调用forwork方法实现请求转发(路径不发生改变)
context.getRequestDispatcher("/context2").forward(req, resp);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<servlet>
<servlet-name>ContextServletTest2</servlet-name>
<servlet-class>per.mobian.servlet.ContextServletTest2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServletTest2</servlet-name>
<url-pattern>/context2</url-pattern>
</servlet-mapping>

<context-param>
<param-name>ContextServletTest2</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>

<servlet>
<servlet-name>ContextServletTest3</servlet-name>
<servlet-class>per.mobian.servlet.ContextServletTest3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServletTest3</servlet-name>
<url-pattern>/context3</url-pattern>
</servlet-mapping>

</web-app>

执行结果:

JavaWeb(二)_java_05

补充请求转发与重定向的区别

请求转发:

JavaWeb(二)_xml_06

重定向:

JavaWeb(二)_ide_07

4、读取资源文件

测试代码:

package per.mobian.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ContextServletTest4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取properties文件的位置,并且放置在上下文中
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
//将获取到的资源放入Prpperties中
prop.load(is);
//获取相应的信息
String name = prop.getProperty("name");
String password = prop.getProperty("password");
resp.getWriter().print(name+" : "+password);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//db.properties
name=mobian
password=123456
<servlet>
<servlet-name>ContextServletTest3</servlet-name>
<servlet-class>per.mobian.servlet.ContextServletTest3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServletTest3</servlet-name>
<url-pattern>/context3</url-pattern>
</servlet-mapping>

执行结果:

JavaWeb(二)_xml_08

注意事项:

此处的properties文件,注意存放的位置。由于maven打war包时本身的特性,会出现将不符合规定的文件格式自动屏蔽,所以需要在pom.xml文件中,添加上相应的过滤器

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

6.6、HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse

  • 如果要获取客户端请求过来的参数,找HttpServletRequest
  • 如果要给客户端响应一些信息,找HttpServletResponse
1、简单分类

负责向浏览器发送的数据:

public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头的方法:

//HttpServletResponse类中
public void setCharacterEncoding(String charset);
public void setContentLength(int len);
public void setContentLengthLong(long len);
public void setContentType(String type);

//ServletResponse类中
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public void setHeader(String name, String value);
public void addHeader(String name, String value);
public void setIntHeader(String name, int value);

响应状态码:

public static final int SC_CONTINUE = 100;
public static final int SC_SWITCHING_PROTOCOLS = 101;
public static final int SC_OK = 200;
public static final int SC_CREATED = 201;
public static final int SC_ACCEPTED = 202;
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
public static final int SC_NO_CONTENT = 204;
public static final int SC_RESET_CONTENT = 205;
public static final int SC_PARTIAL_CONTENT = 206;
public static final int SC_MULTIPLE_CHOICES = 300;
public static final int SC_MOVED_PERMANENTLY = 301;
public static final int SC_MOVED_TEMPORARILY = 302;
public static final int SC_FOUND = 302;
public static final int SC_SEE_OTHER = 303;
public static final int SC_NOT_MODIFIED = 304;
public static final int SC_USE_PROXY = 305;
public static final int SC_TEMPORARY_REDIRECT = 307;
public static final int SC_BAD_REQUEST = 400;
public static final int SC_UNAUTHORIZED = 401;
public static final int SC_PAYMENT_REQUIRED = 402;
public static final int SC_FORBIDDEN = 403;
public static final int SC_NOT_FOUND = 404;
public static final int SC_METHOD_NOT_ALLOWED = 405;
public static final int SC_NOT_ACCEPTABLE = 406;
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
public static final int SC_REQUEST_TIMEOUT = 408;
public static final int SC_CONFLICT = 409;
public static final int SC_GONE = 410;
public static final int SC_LENGTH_REQUIRED = 411;
public static final int SC_PRECONDITION_FAILED = 412;
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
public static final int SC_REQUEST_URI_TOO_LONG = 414;
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public static final int SC_EXPECTATION_FAILED = 417;
public static final int SC_INTERNAL_SERVER_ERROR = 500;
public static final int SC_NOT_IMPLEMENTED = 501;
public static final int SC_BAD_GATEWAY = 502;
public static final int SC_SERVICE_UNAVAILABLE = 503;
public static final int SC_GATEWAY_TIMEOUT = 504;
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
2、常见应用
  1. 向浏览器输出消息(getWriter().print())
  2. 下载文件
  1. 要下载文件的路径
  2. 下载的文件名
  3. 让浏览器能够支持下载所需要的信息
  4. 获取下载文件的输入流
  5. 创建缓冲区
  6. 获取OutputStream对象
  7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端

测试代码:

package pers.mobian.response;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileResponse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 要下载文件的路径
String realPath = "E:\\ideaWorkSpace\\16_maven_03\\3_response_01\\target\\classes\\1.jpg";
// 2. 下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3. 让浏览器能够支持下载所需要的信息
resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);

//设置字符编码,防止被下载的文件名含中文无法显示
//resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));

// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
in.close();
out.close();

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、验证码功能

测试代码:

package pers.mobian.response;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageResponse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置图片自动刷新
resp.setHeader("refresh","3");

//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
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));
g.drawString(makeNum(),0,20);

//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragram","no-cache");
ImageIO.write(image,"jpg",resp.getOutputStream());

}

private String makeNum() {
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 7 - num.length(); i++){
sb.append("0");
}
num = sb.toString() + num;
return num;
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

执行结果:

JavaWeb(二)_ide_09

4、重定向(重点)

web资源B收到客户端请求后,他会通知客户端去访问另一个资源C,这个过程叫做重定向

常见场景:

  • 用户登录
public void sendRedirect(String location) throws IOException;

测试代码

package pers.mobian.response;

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 RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/image");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}

执行结果:

JavaWeb(二)_ide_10

重定向的测试小案例:

测试代码:

//RedirectServletTest02.java
package pers.mobian.response;

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 RedirectServletTest02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String usename = req.getParameter("usename");
String password = req.getParameter("password");
System.out.println(usename+":"+password);

resp.sendRedirect("/success.jsp");

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//web.xml
<servlet>
<servlet-name>RedirectServletTest02</servlet-name>
<servlet-class>pers.mobian.response.RedirectServletTest02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RedirectServletTest02</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<%--index.jsp--%>
<html>
<body>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
username:<input type="text" name="username">
<br>
password:<input type="password" name="password">
<br>
<input type="submit">
</form>
</body>
</html>


<%--success.jsp--%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>

6.7、HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息

1、获取前端传递的参数,并且请求转发

测试代码:

package pers.mobian.request;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class RequestTest01 extends HttpServlet {
@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");
System.out.println("==================");
System.out.println(username);
System.out.println(password);
String[] hobbys = req.getParameterValues("hobbys");
System.out.println(Arrays.toString(hobbys));
System.out.println("==================");

//此处使用的是请求转发的形式
req.getRequestDispatcher("/success.jsp").forward(req, resp);
//此时使用的是重定向的形式
//resp.sendRedirect("success.jsp");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<div>
<form action="${pageContext.request.contextPath}/login" method="post">
姓名:<input type="text" name=username></br>
密码:<input type="password" name=password><br>
爱好:
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="代码">代码
<input type="checkbox" name="hobbys" value="跑步">跑步
<input type="checkbox" name="hobbys" value="理财">理财
<input type="submit">
</form>
</div>
</body>
</html>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>pers.mobian.request.RequestTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>

</web-app>

执行结果:

JavaWeb(二)_java_11

JavaWeb(二)_xml_12

重点:重定向和转发的区别:

相同点:页面都会实现跳转

不同点:

  • 请求转发的时候,url不会发生变化 307
  • 重定向的时候,url地址栏会发生变化 302

7、Cookie、Session

7.1、会话

**会话:**用户打开一个浏览器,访问多个web资源,再关闭浏览器,这个过程称之为会话啊

**有状态会话:**之前访问过某web资源,然后再次访问,服务端知道你曾经访问过,称之为有状态会话

一个网站如何证明你来过?

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
  2. 服务器等级你来过,下次你来的时候来匹配你;session

7.2、保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

session

  • 服务器技术,可以保存用户的会话信息。我们可以把信息或者数据放在session中

常见:网站登录之后,你下次不用再次登录,第二次直接访问

7.3、Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie

测试代码:

package pers.mobian.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookieTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
req.setCharacterEncoding("utf-8");

PrintWriter out = resp.getWriter();
//Cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();

//判断Cookie是否存在
if (cookies != null) {
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取Cookie的名字
if (cookie.getName().equals("lastLoginTime")) {
//获取cookie中的值
long lastLonginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLonginTime);
out.write(date.toLocaleString());
}
}

} else {
out.write("这是第一次访问");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//给cookie设置一个有效期
cookie.setMaxAge(24*60*60);

resp.addCookie(cookie);

}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

执行结果:

JavaWeb(二)_xml_13

cookie:一般会保存在本地的用户目录AppData下

cookie相关信息:

  • 一个Cookie只能保存一个信息
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
  • cookie大小限制4kb
  • 浏览器上限300个cookie

删除Cookie

  • 不设置有效期,关闭浏览器,自动失效
  • 设置有效期时间为0

编码解码

//给Cookie对应格式的编码
resp.getWriter().print(URLDecoder.decode(cookie.getValue(),"UTF-8"));

//获取Cookie值时,对其进行解码
Cookie cookie = new Cookie("name", URLEncoder.encode("默辨","utf-8"));

7.4、Session(重点)

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户浏览器,浏览器保存(可以保存多个)
  • Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建

JavaWeb(二)_java_14

JavaWeb(二)_ide_15

补充一个:

JavaWeb(二)_ide_16

使用场景:

  • 保存一个登录用户的信息
  • 购物车信息
  • 在整个网站中经常会使用的数据,我们将它保存在Session中

功能描述:

JavaWeb(二)_ide_17

测试代码:

SessionTest01

package pers.mobian.session;

import pers.mobian.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");

//得到Session
HttpSession session = req.getSession();

//给Session中存东西
//session.setAttribute("name","mobian");
session.setAttribute("name",new Person("mobian","22"));

//获取Session的ID
String id = session.getId();

//判断Session是不是新创建的
if(session.isNew()){
resp.getWriter().write("新session值是:"+session);
resp.getWriter().write("新sessionID值是:"+id);
} else {
resp.getWriter().write("这是一个旧的session:"+session);
resp.getWriter().write("这是一个旧的sessionID:"+id);
}


}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

SessionTest02

package pers.mobian.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionTest02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");


HttpSession session = req.getSession();

Object name = session.getAttribute("name");
System.out.println(name.toString());

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

SessionTest02

package pers.mobian.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionTest03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">


<servlet>
<servlet-name>SessionTest01</servlet-name>
<servlet-class>pers.mobian.session.SessionTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionTest01</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>




<servlet>
<servlet-name>SessionTest02</servlet-name>
<servlet-class>pers.mobian.session.SessionTest02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionTest02</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>SessionTest03</servlet-name>
<servlet-class>pers.mobian.session.SessionTest03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionTest03</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>

<!--设置Session默认的失效时间-->
<session-config>
<!--1分钟后Session自动失效,以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>

</web-app>

8、JSP

8.1、什么是JSP

Java Server Pages:Java服务器端页面,和Servlet一样,用于动态web技术!

特点:

  • 写JSP就像在写HTML
  • 区别:
  • HTML只给用户提供静态的数据
  • JSP页面中可以嵌入JAVA代码,为用户提供动态数据
8.2、JSP原理

1、在本地对应目录下,存在相应的文件

C:\Users\Mrpan\.IntelliJIdea2018.2\system\tomcat\Unnamed_16_maven_03_2\work\Catalina\localhost\ROOT\org\apache\jsp

JavaWeb(二)_ide_18

2、打开index_jsp.java查看jsp的源码

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
}

其中的HttpJspBase类继承自HttpServlet,所以JSP本质上也是一个Servlet

3、IDEA中的html界面,在后台文件中是jsp界面,只是系统帮我们写成了jsp

JavaWeb(二)_xml_19

4、关键方法

//初始化
public void _jspInit() {}
//销毁
public void _jspDestroy() {}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

在JSPService方法中

1)判断请求

if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}

2)内置一些对象

final javax.servlet.jsp.PageContext pageContext;//页面上下问
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContext application;//applicationContext
final javax.servlet.ServletConfig config;//config
javax.servlet.jsp.JspWriter out = null;/out
final java.lang.Object page = this;//page:当前

HttpServletRequest request//请求
HttpServletResponse response//响应

3)输出页面前增加的代码

response.setContentType("text/html");//设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;

4)以上的这些对象我们可以在JSP页面中直接使用

执行流程图

JavaWeb(二)_xml_20

补充一句:

当程序启动以后,idea文件目录下的work文件夹会重新生成,新生成的文件夹。

C:\Users\Mrpan\.IntelliJIdea2018.2\system\tomcat\Unnamed_16_maven_03_2

并且.java文件和.class文件均在work目录下的对应路径中。当客户端访问访问对应的jsp页面之后,系统才会生成对应的两个文件。对应代码也在其中。

work\Catalina\localhost\ROOT\org\apache\jsp

JavaWeb(二)_ide_21

8.3、 JSP基础语法

JSP作为Java技术的一种应用,它拥有自己扩充的一些语法

补充:为方便调试,可以使用热部署,详情请参考https://www.jianshu.com/p/a84aa07437cf

1、JSP表达式
<%--JSP表达式
作用:将程序输出到客户端
<%= 表达式或者变量%>--%>

<%= new java.util.Date%>
2、JSP脚本
<html>
<body>
<h2>Hello World!</h2>
<%= new java.util.Date() %>

<%
int sum= 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.print("<h1>sun:"+sum+"<h1>");
%>
</body>
</html>

执行结果:

JavaWeb(二)_java_22

3、JSP脚本片段的再实现
<%
for (int i = 0; i < 5; i++) {
%>
<h1>hello world <%= i %></h1>
<%
}
%>

执行结果:

JavaWeb(二)_ide_23

4、JSP声明
<%!
static {
int i = 1;
}
private int b= 2;
public void method() {
System.out.println("3");
}

JavaWeb(二)_java_24

JSP声明:会变编译到JSP生成的Java类中,其他的会被生成到_jspService方法中

即在JSP中嵌入java代码。

4、汇总
<% %>  //插入JSP片段
<%= %> //出入JSP表达式
<%! %> //插入JSP语句,

//在客户端中html的注释会被显示出来,但是JSP的注释不会显示,为了更好的安全性,建议式用JSP的注释
<%-- --%> //JSP的注释
<!-- --> //html的注释
8.4、JSP指令
//此用法类似于java种的导入包
<%@page import="java.util.Date" %>
//此用法表示,如果当前页面有错误,则跳转到相应的界面
<%@page errorPage="xxx.jsp" %>
//此用法表示,设置该页面为错误页面,可在自定义的404等错误中设置
<%@page isErrorPage="true" %>

//两种方式可以引入新的页面,可以将引入的新的界面当作头部或者尾部
<%@include file="xxx.jsp"%>//此方式是将两个界面合二为一(变成java代码)
<jsp:include page="xxx.jsp"></jsp:include>//此方法是将界面进行拼接(类似于链接,建议使用此种方法)

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
//此方法的使用,可以标注出现对应的错误类型以后跳转的页面
<error-page>
<error-code>404</error-code>
<location>/xxx.jsp</location>
</error-page>
</web-app>
8.5、9大内置对象
  • PageContext:存东西
  • Request:存东西
  • Response
  • Session:存东西
  • Application<–SerlvetContext:存东西
  • config<–ServletConfig
  • out
  • page(不同)
  • exception

测试代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<%--内置对象--%>
<%

pageContext.setAttribute("name1", "mobian1");//保存的数据只在一个页面中有效
request.setAttribute("name2", "mobian2");//保存的数据只会在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3", "mobian3");//保存的数据只会在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4", "mobian4");//保存的数据只会在服务器中有效,从打开服务器到关闭服务器

%>

<%--脚本片段中的代码,会被原封不动的生成到.jsp,java中--%>
<%
//从pageContext取出
//从底层到高层(作用域):page > request > session > application
pageContext.getAttribute("name1");
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");
%>


<h2>${name1}</h2>
<h2>${name2}</h2>
<h2>${name3}</h2>
<h2>${name4}</h2>
<h2>${name5}</h2>//使用EL表达式的时候,如果寻找的值不存在,则不会显示

<%
//两种不同的请求转发的写法
pageContext.forward("/index.jsp");//前端
request.getRequestDispatcher("/index.jsp").forward(request, response);//后台

%>

</body>
</html>

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用了
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可以使用,比如:聊天数据

8.6、JSP标签、JSTL标签、EL表达式

依赖:

<!--JSTL依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<!--JSTL依赖的标签库-->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
1、EL表达式:${}
  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
2、JSP标签

测试代码:

<%--jsplabel.jsp--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--jsp:include标签--%>
<%--等价于:http://localhost:8080/index.jsp?name=mobian&age=22--%>
<jsp:forward page="index.jsp">
<jsp:param name="name" value="mobian"></jsp:param>
<jsp:param name="age" value="22"></jsp:param>
</jsp:forward>

</body>
</html>

<%--index.jsp--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
名字:<%= request.getParameter("name")%>
年龄:<%= request.getParameter("age")%>
</body>
</html>

执行结果:

JavaWeb(二)_xml_25

用JSP书写等效的JavaBean

<%--
Created by IntelliJ IDEA.
User: Mrpan
Date: 2020/3/3
Time: 19:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<%
// People people = new People();
// people.setAddress();
// people.setId();
// people.setAge();
// people.setName();
%>
<%--上下等价--%>
<jsp:useBean id="people" class="pers.mobian.pojo" scope="page"/>
<jsp:setProperty name="people" property="address" value="重庆"/>
<jsp:setProperty name="people" property="id" value="666"/>
<jsp:setProperty name="people" property="age" value="22"/>
<jsp:setProperty name="people" property="name" value="默辨"/>

<%--
<%= people.getAddress()%>
--%>
姓名:<jsp:getProperty name="people" property="name"/>
id:<jsp:getProperty name="people" property="id"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>

</body>
</html>
3、JSTL表达式

需要引入JSTL核心标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

JSTL标签库的使用就是为了弥补HTML标签的不足,它自定义许多标签,可以供我们使用,标签的功能和Java代码一样

使用场景:

  • 核心标签(掌握部分)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 格式化标签
<%@ taglib prefix="fmt"  uri="http://java.sun.com/jsp/jstl/fmt" %>
  • SQL标签
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
  • XML标签
<%@ taglib prefix="x"  uri="http://java.sun.com/jsp/jstl/xml" %>
  • JSTL函数
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

JSTL标签库使用步骤:

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat也需要引入jstl的包,否则会报错:JSTL解析错误

测试代码:

c:if

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>if测试</h1>
<form action="jstltest1.jsp" method="post">
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">

</form>
<c:if test="${param.username == 'admin'}" var="isAdmin">
<c:out value="管理员欢迎你" />
</c:if>
<c:out value="${isAdmin}"/>

</body>
</html>

执行结果:

JavaWeb(二)_xml_26

c:choose

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
c
<c:set var="score" value="33"/>
<c:choose>
<c:when test="${score>=90}">
你的成绩为A
</c:when>
<c:when test="${score>=80}">
你的成绩为B
</c:when>
<c:when test="${score>=70}">
你的成绩为C
</c:when>
<c:when test="${score<=60}">
你的成绩为D
</c:when>
</c:choose>
</body>
</html>

JavaWeb(二)_xml_27

c:forEach

<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%

ArrayList<String> person = new ArrayList<>();
person.add("张三");
person.add("李四");
person.add("王五");
request.setAttribute("persons",person);
%>
<%--
var:每一次要遍历出来的变量
items:要遍历的对象
begin:从哪里开始
end:从哪里结束
step:步长
--%>
<c:forEach var="person" items="${persons}">
<c:out value="${person}"/><br>
</c:forEach>
<hr>

<c:forEach var="person" items="${persons}" begin="1" end="2" step="1">
<c:out value="${person}"/><br>
</c:forEach>
</body>
</html>

JavaWeb(二)_java_28

9、JavaBean

实体类

JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库字段做映射 ORM、


10、MVC三层架构

MVC:Model View Controller 模型、视图、控制器

10.1、之前处理方式

JavaWeb(二)_ide_29

用户直接访问控制层,控制层可以直接操作数据库:

//弊端:程序会十分臃肿,不利于维护
//servlet代码的作用:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
servlet -- CRUD --> 数据库

//架构:没有什么是加一层解决不了的,如果还解决不了,加两层

10.2、MVC三层架构

JavaWeb(二)_xml_30

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD(DAO)

View

  • 展示数据
  • 提供链接发起Servlet请求(a,form,img…)

Controller (Servlet)

  • 接收用户的请求:(req:请求参数、Session信息)
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)--->交给业务层处理登录业务(判断用户名密码是否正确:事物)--->DAO层查询用户名和密码是否正确--->数据库

11、Filter(重点)

Filter:过滤器,用来过滤网站的数据

  • 处理中文乱码
  • 验证登录…

JavaWeb(二)_java_31

Filter开发步骤:

  1. 导包(import javax.servlet.*;)
  2. 编写过滤器
  1. 编写过滤器
package pers.mobian.filter;

import javax.servlet.*;
import java.io.IOException;

public class CharacterEncodingFilter implements Filter {

//初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("方法被初始化方法");
}

//Chain:链
/*
* 1.过滤中的所有代码,在过滤特定请求的时候都会执行
* 2.必须要让过滤继续进行
* chain.doFilter(request, response);
* */
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//设置响应的编码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");

System.out.println("过滤器方法执行前");
chain.doFilter(request, response);//让我们的请求继续走,如果不写,程序到这里就会被拦截停止
System.out.println("过滤器方法执行后");

}

//销毁;web服务器关闭的时候,过滤会被销毁
@Override
public void destroy() {
//可以在该方法内进行相关的操作
// System.gc();
System.out.println("方法被销毁方法");

}
}
  1. 编写测试类
package pers.mobian.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 ServletTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("我是中文");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
  1. 编写对应的web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<!--同一个请求方法,对应两个不同的映射-->
<servlet>
<servlet-name>ServletTest01</servlet-name>
<servlet-class>pers.mobian.servlet.ServletTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest01</servlet-name>
<url-pattern>/servlet/s</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletTest01</servlet-name>
<url-pattern>/s</url-pattern>
</servlet-mapping>

<!--使用自定义的过滤器,过滤指定目录-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>pers.mobian.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>

</web-app>

执行结果:

JavaWeb(二)_xml_32

12、监听器

实现一个监听器的接口(方法很多)

  1. 编写一个监听器,实现监听器的接口
package pers.mobian.listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//统计网站在线人数:统计session
public class OnlineCountListener implements HttpSessionListener {
//创建session监听,看你的一举一动
//一旦创建Session就会出发这个事件
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
//打印输出session的Id
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount == null) {
onlineCount = 1;
} else {
onlineCount++;
}
ctx.setAttribute("OnlineCount", onlineCount);


}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
//打印输出session的Id
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount == null) {
onlineCount = 0;
} else {
onlineCount--;
}
ctx.setAttribute("OnlineCount", onlineCount);
}
}
  1. 编写对应的web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">

<!--配置监听器-->
<listener>
<listener-class>pers.mobian.listener.OnlineCountListener</listener-class>
</listener>

<session-config>
<!--设置session的有效时长-->
<session-timeout>1</session-timeout>
</session-config>

</web-app>
  1. 编写对应的index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<h1>当前的在线人数是:<%= this.getServletConfig().getServletContext().getAttribute("OnlineCount") %> </h1>

</body>
</html>

执行结果:

JavaWeb(二)_ide_33

JavaWeb(二)_xml_34

JavaWeb(二)_ide_35

执行结果解释:第一张图片为自带浏览器访问,第二张图片为谷歌浏览器访问,第三张图片为一分钟以后的再次访问。当浏览器第一次访问资源的时候,会根据java类进行对应的操作,当用谷歌浏览器的时候,为新的客户端,所以访问对应的资源时,对于新的请求,又会出现对应的session。由于在web.xml中设置了session的过期时间,即此时之前的访问留下的session全部清除,新的session出现。

注意:有时候会出现第一次访问但是显示的session不为1的情况,此时说明浏览器访问对应的资源到请求资源成功过程,不止进行了一次的访问。

13、过滤器、监听器的常见应用

1、监听器:GUI编程中出现

2、过滤器:实现登录的权限拦截

拦截登录小案例:

  1. 编写初始的登录界面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<h1>登录</h1>
<form action="/servlet/logintest01">
用户名:<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
  1. 编写对应的测试类LoginTest01
package pers.mobian.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 LoginTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//获取前端的参数
String username = req.getParameter("username");

if(username.equals("admin")) {
req.getSession().setAttribute("user_session",req.getSession().getId());
resp.sendRedirect("/success.jsp");
} else{
resp.sendRedirect("/error.jsp");
}
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
  1. 编写对应的登录成功和失败的jsp界面success.jsp、error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>未知错误</h2>
<a href="/login.jsp">退出</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录成功</h1>
<a href="/login.jsp" >注销</a>
</body>
</html>
  1. 编写对应的过滤器类LoginFilter.java
package pers.mobian.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse)resp;
HttpServletRequest request = (HttpServletRequest)req;

if(request.getSession().getAttribute("user_session") == null){
response.sendRedirect("error.jsp");
}
chain.doFilter(req,resp);
}
@Override
public void destroy() {
}
}
  1. 添加对应的映射关系
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>LoginTest01</servlet-name>
<servlet-class>pers.mobian.servlet.LoginTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginTest01</servlet-name>
<url-pattern>/servlet/logintest01</url-pattern>
</servlet-mapping>

<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>pers.mobian.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/success.jsp</url-pattern>
</filter-mapping>


</web-app>

14、文件上传

1、准备工作

对于文件上传,浏览器在上传过程中以流的形式提交到服务器端。

一般选择采用apache的开源工具common-fileupload这个文件上传组件。

其中,common-fileupload是依赖于common-io这个包,即需要下载两个jar包。

对应的maven依赖如下:

<!--文件下载的依赖jar包-->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>


<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>

2、使用类介绍

文件上传的注意事项:(面试)

  1. 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
  2. 为了防止文件覆盖的现象发生,要 为上传的文件产生一个唯一的文件名,如-时间戳、-uuid、-md5(加密算法)、-位运算算法
  3. 要限制上传文件的最大值
  4. 可以限制上传文件的类型,在收到上传文件名,判断后缀名是否合法

略。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。JavaWeb大部分都包含了,加油,我实在不想继续往下写了!!!


标签:http,JavaWeb,resp,public,import,servlet,javax
From: https://blog.51cto.com/u_15942107/6019965

相关文章

  • 【Javaweb】Servlet四 | ServletConfig类|ServletContext类
    ServletConfig类是Servlet程序的配置信息类。ServletConfig类的三大作用1、可以获取Servlet程序的别名servlet-name的值System.out.println("HelloServlet程序的别名"+s......
  • 【Javaweb】Servlet三|实现Servlet程序的几种方法及Servlet继承体系说明
    GET和POST请求的分发处理代码如下注意页面要和index位置一样否则浏览器找不到注意大小写HttpServletRequesthttpServletRequest=(HttpServletRequest)servletReq......
  • 【Javaweb】servlet二
    servlet程序常见错误1、url-pattern路径没有以/打头2、servlet-name配置的值不存在3、servlet-class标签的全类名配置错误servlet-url地址如何定位到servlet程序去访......
  • JavaWeb-Request&Response
    JavaWeb-Request&Response1,Request和Response的概述Request是请求对象,Response是响应对象。这两个对象在我们使用Servlet的时候有看到:此时,我们就需要思考一个问题reques......
  • 【Javaweb】servlet一
    什么是servlet1、servlet是JavaEE规范之一,规范就是接口。2、servlet是Javaweb三大组件之一。三大组件分别是:servlet程序、filter过滤器、listener监听器。3、servlet是......
  • JavaWeb项目中web.xml配置文件<servlet-class>…</servlet-class>中的路径出现问题以及服
    问题如图 原因:1.改变了WEB-INF文件夹下lib文件夹下servlet-api.jar的路径2.缺失lib文件夹下的servlet-api.jar,没有添加到库中解决办法:不要改动lib文件的路......
  • JavaWeb开发中在服务器常用命令集锦
    基本的lsmvmidir就不说了。一.后端部署1.1启动jar包#默认会将所有日志存放到一个当前目录中新建的nohup.out文件中nohupjava-jar-Duser.timezone=GMT+8ap......
  • JavaWeb(一)
    JavaWebjava+webTomcat服务器及Maven部分1、基本概念1.1、前言web开发:web:网页静态webhtml、css提供给所有人看的数据始终不会发生变化动态web淘宝......
  • 【Javaweb】给tomcat添加第三方jar包
    就是复制到lib文件夹里面之后点击jar包右键 选择modulelibrary,点击ok就可以了 ......
  • 【Javaweb】动态web工程目录介绍
    src存放自己编写的Java源代码web专门用来存放web工程的资源文件(html页面、css文件、js文件等等)WEB-INF是一个受服务器保护的目录,浏览器无法直接访问此目录的内容web.......