目录
2.创建一个类,实现Servlet接口,并且重写接口方法service
3.在类上使用@WebServlet(" /demo ")注解,配置Servlet
2.初始化,调用Servlet的init()方法初始化Servlet的对象——只调用一次
(5)Servlet urlPattern配置:注解的:路径配置
一、HTTP协议
1.基本概念
2. HTTP请求数据格式
<1>常见的请求方式:GET,POST
<2>请求数据的三部分:
1;请求行:HTTP请求中的第一行数据,请求行包含三块内容,分别是 GET[请求方式] /[请求URL路径] HTTP/1.1[HTTP协议及版本]。(GET请求方式再此行存放数据)
备注:请求方式有七种,最常用的是GET和POST
2; 请求头: 第二行开始,格式为key: value形式
3; 请求体: POST请求的最后一部分,存储请求参数(post请求方式住在此行存放请求参数)
备注:请求体与上一个请求头用空白行隔行
<3>常见的请求头
*Host: 表示请求的主机名
*User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ...Chrome/79,IE 浏览器的标识类似Mozilla/5.0 (Windows NT ...)like Gecko;
*Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
*Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
*Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。
3.HTTP响应数据格式
-
响应行:响应数据的第一行,响应行包含三块内容,分别是 HTTP/1.1[HTTP协议及版本] 200[响应状态码] ok[状态码的描述]
-
响应头:第二行开始,格式为key:value形式
响应头中会包含若干个属性,常见的HTTP响应头有:
Content-Type:表示该响应内容的类型,例如text/html,image/jpeg; Content-Length:表示该响应内容的长度(字节数); Content-Encoding:表示该响应压缩算法,例如gzip; Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
-
响应体: 最后一部分。存放响应数据
上图中<html>...</html>这部分内容就是响应体,它和响应头之间有一个空行隔开。
-
常见的状态码:200响应成功,404URL错误,500代码错误
<4>状态响应码
二、Tomcate入门使用详解
1.目录结构
备注:以后把web项目打成war包放入webapps中就可以在网站浏览了
2.启动Tomcate
启动后,通过浏览器访问 http://localhost:8080
能看到Apache Tomcat的内容就说明Tomcat已经启动成功。
==注意==: 启动的过程中,控制台有中文乱码,需要修改conf/logging.prooperties
把UTF-8改为GBK。
3.关闭Tomcate
关闭有三种方式
-
直接x掉运行窗口:强制关闭[不建议]
-
bin\shutdown.bat:正常关闭
-
ctrl+c: 正常关闭
4.配置
<1>修改端口号
-
Tomcat默认的端口是8080,要想修改Tomcat启动的端口号,需要修改 conf/server.xml
注: HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。
<2>启动时可能出现的错误
Tomcat的端口号取值范围是0-65535之间任意未被占用的端口,如果设置的端口号被占用,启动的时候就会包如下的错误
-
Tomcat启动的时候,启动窗口一闪而过: 需要检查JAVA_HOME环境变量是否正确配置
<3>部署
-
Tomcat部署项目: 将项目放置到webapps目录下,即部署完成
一般JavaWeb项目会被打包称==war==包,然后将war包放到Webapps目录下,Tomcat会自动解压缩war文件
<4>web项目结构
<5>在idea中创建maven web项目
方法一:
在pom.xml中
此时还缺少个Java文件夹和Resources.xml文件
此时就完成了。
方法二:没有骨架
缺少web的核心文件夹和配置文件
我们双击java文件夹会出现:
本来web目录与src同级,我们将其拉入src即可
最后在pom.xml里加上这个
<6>在idea中集成Tomcate
在这个模块导入工程,否则无法在idea中运行
完成配置。
<7>tomcat插件替代
1.在pom.xml中配置插件坐标
源码:
<!-- tomcat插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8081</port>
</configuration>
</plugin></plugins>
</build>
2.运行
3.寻找网址
完成使用。
三、Servlet
(1)初始化Servlet
1.导入Servlet依赖
<!-- 必须设置有效范围scope,在编译时无效,因为在tomcat中有servlet的jar包,会报错-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
2.创建一个类,实现Servlet接口,并且重写接口方法service
public class demo implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("你好");
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
3.在类上使用@WebServlet(" /demo ")注解,配置Servlet
4.启动tomcat打开网页在网址后面输入注解内容
5.备注:404错误:错误一,错误二
<1> 404错误1
使用注解WebServlet配置Servlet报404错误的原因
Servlet3.0之后新增了注解,用于简化Servlet、Filter及Listener的声明,这样就在配置Servlet的时候多了一个选择。Servlet3.0的部署描述文件web.xml的顶层标签<web-app>有一个metadata-complete属性,该属性为true,则容器在部署时只依赖部署描述文件,忽略所有标注,如果不配置该属性,或者将其设置为false,则表示启动标注支持。当metadata-complete="false"时,web.xml和注解对于Servlet的影响同时起作用,两种方法定义的url-partten都可以访问到该Servlet,但是当通过web.xml定义的url-partten访问时,注解定义的属性(初始化参数等)将失效。
但是,我们要知道JDK是在5.0之后才支持注解特性的,所以要想使用Servlet3.0的这个新特性必须JDK5.0以后的版本。而Tomcat容器是在7.0以后才开始支持此特性。所以通常使用WebServlet注解报404错误的原因可以总结如下:
1.使用的是JDK5.0以前的版本;
2.使用的是Tomcat7.0更早的版本;
3.使用了web.xml文件但是web-app标签的version属性不为3.0,导致容器没有按照Servlet 3.0版本正确配置;
转载于:https://www.cnblogs.com/SacredOdysseyHD/p/9063141.html
<2>404错误2
这里的war包选错也会访问不到servlet
(2)Servlet的在Tomcat的执行流程
******* Servlet的对象是在第一次访问servlet时在Tomcat中创建
(3)生命周期
1.加载和实例化
若是如图配置:
服务器启动时就会创建Servlet的对象,节省时间。
2.初始化,调用Servlet的init()方法初始化Servlet的对象——只调用一次
/**
* 初始化方法
*1.调用时机:第一次被访问时候调用
* 2.调用次数:一次
*
* @param servletConfig
* @throws ServletException
*/
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("你只能调用我一次");
}
3.请求处理 service()
/**
* 1.执行时间:每次被访问Servlet时都会使用这个方法
* 2.执行次数:多次
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("你好");
}
4.服务终止 destory()
/**
* 1.调用时机:释放资源时或者关闭服务器时
* 2.执行次数:一次
*/
public void destroy() {
}
5.其他方法1:getServletInfo()
/**
*一般返回null或者空字符串
*
* @return
*/
public String getServletInfo() {
return "";
}
6.其他方法2:
/**
* 返回值是一个对象
* 我们把init()里的局部变量的生效范围扩大就行了
* private ServletConfig servletConfig;声明一个全局变量
* 在initial()里为全局变量赋值
* this.servletConfig = servletConfig;
* 这时在getServletConfig()里可以写
* return servletConfig;
*
* @return
*/
public ServletConfig getServletConfig() {
return servletConfig;
}
(4)体系结构
HttpServlet的原理:在HttpS这个接口里定义了一些逻辑:在tomcat接收到的是get或者post等等请求方式时候,它会和对应的字符串比较,最后知道是哪种。是哪种就执行对应的方法。这些方法,在这个接口里都定义好了。我们写其他类时若继承这个HttpS接口时候,需要先重写对应的方法,重写的方法是你对该种请求方式的回应,以表示你完成了你看到了这个请求,也分辨了这时什么请求了。 不过在执行前,你会走一遍这个接口的逻辑,以选择方法。
(5)Servlet urlPattern配置:注解的:路径配置
1.
2.
.
(6)xml配置Servlet
<!-- 全类名
-->
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.wangrongxiao.tomcatDemo1.demo</servlet-class>
</servlet>
<!-- Servlet 访问路径-->
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
(7)Request
1.Request的继承体系
无论是servlet还是request还是response的对象都是由tomcat创建的。
RequestFacade实现类也是在tomcat中实现的。
2.Request获取请求数据
&&&&&获取请求行,请求头的数据都不太常用。这里重点说下获取请求参数。
<1>由于GET请求方式,他的请求参数放在请求行里,这里有固定的获取方法
//String get QueryString() //返回值是字符串
@WebServlet("/demo3")
public class demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queryStrings = request.getQueryString();//返回值是字符串
System.out.println(queryStrings);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
<2>第二种是POST的请求方式
有两种输入流的方法:1.getInputStream():用于发送的数据类型是图片或者文件
2.getReader():用于发送的纯文本类型的数据(常用)
第一步创建一个简易的表单:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
//访问路径为/工程名/servlet路径
<form action="/tomcate_demo/demo3" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="checkbox" name="hobby" value="1"> 游泳
<input type="checkbox" name="hobby" value="2"> 爬山 <br>
<input type="submit">
</form>
</body>
</html>
这里的代码我们主要看doPost():
第二步:这里使用的是getReader()字符输入流,并使用readLine()方法来读取数据并且输出出来
@WebServlet("/demo3")
public class demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queryStrings = request.getQueryString();
System.out.println(queryStrings);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取数据
BufferedReader readers = request.getReader();
// 读取数据
String line = readers.readLine();//读取一行
System.out.println(line);
// this.doGet(request, response);
}
}
3.Request通用方式获取请求参数
Map集合里类型名和值一一对应的,类型名不允许一样,这里Request把相同类型名有多个值的情况,进行了处理,他把不同的值放进一个数组里来与类型名进行一对一的对应。
这里有三个方法:****第一个方法:getParameterMap() 获取Map集合
****** 第二个方法:getParameterValues():知道要获取的数据名包含的数据不只是一个 例如: username:zhangsan,lisi 这个方法会返回一个数组包含这个数据名的所有数据
******第三个方法:getParameter():获取单个的数据名的数据
在这三个方法中,第三个方法是最常用的。
快捷键:
fori快速遍历
iter 快速遍历
@WebServlet("/demo3")
public class demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 第一个方法:getParameterMap() 获取Map集合
// 获取Map集合
Map<String, String[]> parameterMap = request.getParameterMap();
// 遍历Map集合
for (String key : parameterMap.keySet()) {// 例如遍历:username:zhangsan,lisi 第一层遍历map集合的第一个键username
// username:zhangsan,lisi
System.out.print(key+":");
// 获取值
String[] values = parameterMap.get(key);//第二层遍历map集合的第一个键对应的第二个键zhangsan,lisi
for (String value : values) {
System.out.print(value+" ");
}
System.out.println();
}
System.out.println("---------------------");
// 第二个方法getParameterValues():知道要获取的数据名包含的数据不只是一个
// 例如: username:zhangsan,lisi 这个方法会返回一个数组包含这个数据名的所有数据
// 调用getParameterValues()方法
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("---------------------");
// 第三个方法getParameter():获取单个的数据名的数据
// 例如获取用户名username
String parameter = request.getParameter("username");
System.out.println(parameter);
String password = request.getParameter("password");
System.out.println(password);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
4.用idea模板创建Servlet
<1>
<2>
在箭头之的地方修改模板,把需要的函数添加上
此时完成Servlet的快速创建了。
(8)解决Post请求的中文乱码问题
1.我们在用户名里输入中文:
2. 得到的结果:一串中文乱码
3.解决办法:
出现乱码原因是:底层getReader()字符输入流的编码和html网页的编码方式不一样
只需要重新设置一下编码方式就可以了。
// 解决中文乱码问题:post中文乱码
// 设置字符输入流的编码
req.setCharacterEncoding("UTF-8");
(9)解决Get请求的中文乱码问题
产生乱码的根本原因:
在html网页时,我们输入中文,网页用UTF-8的编码方式进行了转码。到了tomcat里进行解码时tomcat用的解码方式不是UTF-8而是ISO-8859-1的方式。
URL的编码过程:一个汉字占三个字节,一个字节8个二进制位然后加上%就转好了
而在tomcat进行了反过程。但是解码方式和编码方式不一致导致了乱码。
解决方案:我们把tomcat解码的内容用相同的方式IOS-8859-1的方式转换成字节数组,
在把字节数组用UTF-8的编码方式进行解码。
// 获取用户名
String username = req.getParameter("username");
// 先对乱码数据进行编码
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
// 字节数组解码
username = new String(bytes,StandardCharsets.UTF_8);
System.out.println(username);
此代码通用解决中文乱码问题。
(10)Request请求转发
转发的意思就是在Servlet里转发数据和需求
在/demo5里发送请求到demo6,这些发送的数据存在request的域中,可以用removeAttribute()来删除。
@WebServlet(urlPatterns = "/demo5")
public class demo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//转发
// 存储数据
req.setAttribute("name","笑笑");
// 转发数据
req.getRequestDispatcher("/demo6").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
在/demo6里接收
@WebServlet(urlPatterns = "/demo6")
public class demo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收数据
Object name = req.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
运行结果:
(11)Response
*1*常用方法
响应数据分为三部分:
1.响应行:
void setStatus(int sc)设置响应状态码
2.响应头:
void setHeader(String name , String value)设置响应头键值对
3.响应体:
PrintWriter getWriter():获取字符输出流
ServletOutputStream getOutputStream():获取字节输出流
*2*重定向
<1>常规重定向方法
在resp1中的代码:
// 重定向
// 回复302的状态响应码,表示自己无法处理该问题,并且返回一个可以处理的URL
// 1.回复302状态码 设置响应状态码的方法:setStatus(int index)
response.setStatus(302);
// 2.回复资源b的路径:
response.setHeader("location","/tomcate_demo/resp2");
<2> 简化重定向:
System.out.println("sorry,resp1处理不了");
/**
// 重定向
// 回复302的状态响应码,表示自己无法处理该问题,并且返回一个可以处理的URL
// 1.回复302状态码 设置响应状态码的方法:setStatus(int index)
response.setStatus(302);
// 2.回复资源b的路径:
response.setHeader("location","/tomcate_demo/resp2");
*/
//上面的代码就是下面这个方法的底层逻辑
// 简化重定向:sendRedirect("B的路径")
response.sendRedirect("/tomcate_demo/resp2");
在resp2:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("可惜我resp2也处理不好");
}
运行结果:
*3*重定向的特点:
<1>浏览器的网址发生了变化
<2>可以重定向到任意资源位置
<3>是两次请求,不能在多个request共享数据
(12)路径问题
什么时候需要加虚拟目录,什么时候不加虚拟目录???
1.明确路径是谁使用的?
>浏览器使用:加虚拟目录
>服务器使用:不加虚拟目录
2.举例
1>超链接
<a herf = "路径"> 加虚拟目录
2>表单
<form action = "路径 ">加虚拟目录
3>Reaquest转发
req.getReaquestDispatcher("URL")不加虚拟目录
4>重定向
resp.sendRedirect("URL")加虚拟目录
3.动态获取虚拟目录路径
String contextPath = request.getContextPath();
//上面的代码就是下面这个方法的底层逻辑
// 简化重定向:sendRedirect("B的路径")
// response.sendRedirect("/tomcate_demo/resp2");
response.sendRedirect(contextPath+"/resp2");
(13)Response响应数据
<1>响应字符流输出
write()方法里有很多类型的数据可以写,其中包括html类型,不过需要
response对象的setContentTYpe(String)方法来确认可识别的输出类型,和输出的编码格式
setContentTYpe(String):
作用一:增加浏览器的数据识别类型
作用二:设置输出流的编码方式,解决中文乱码问题
// 解决中文乱码问题: SetContentType("输出类型;编码方式")
response.setContentType("text/html;charset=UTF-8");//浏览器可以识别text/html了
// Response相应字符流输出数据
// 方法:getWriter()以及write("输出内容")
PrintWriter writer = response.getWriter();
writer.write("666");//输出类型一int型
writer.write("我是你爹");
writer.write("<h1>aaa<h1/>");//输出html类型但是需要用SetContentType("输出类型;编码方式")
<2>响应字节流输出
常用来输出图片,视频,音频。
其实并不常用里面的write()方法来写数据;而是和字节输入流一起使用,来输出图片,音频,视频。
这里使用的IOUtils的Copy方法需要导入依赖,简化输入输出流的对Copy
语法:
IOUtils.Copy(输入流,输出流)
<!-- IOUtils工具类 完成输入输出流的的copy-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
// 第一步字节输入流,读取文件
//路径格式比如d盘:d://+文件夹名/+。。。/+图片名
FileInputStream fis = new FileInputStream("d://photo/ao.jpg");
// 获取Response字节输出流
ServletOutputStream os = response.getOutputStream();
// 完成流的copy
IOUtils.copy(fis,os);
结果:
(14)常用依赖
<!-- 必须设置有效范围scope,在编译时无效,因为在tomcat中有servlet的jar包,会报错-->
<dependencies>
<!-- IOUtils工具类 完成输入输出流的的copy-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
(15)登录注册案例
(让我自己用的)D:\idea_project\loginfirst\login
(16)sqlSessionFactory工具类
每次单独使用这三行代码:都会创建一个sqlSessionFactory连接池,这很浪费资源
我们只需要,让他创建一次就行了。把它放在静态代码块里,一编译就执行一次这个代码(仅执行一次)。
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
解决办法: 我们只需要,让他创建一次就行了。把它放在静态代码块里,一编译就执行一次这个代码(仅执行一次)。
public class SqlSessionFactoryUntil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
调用:
四、JSP
(1)jsp入门
1>概念:jsp 全称Java Server Pages ,Java服务端页面
2>动态的网页技术,其中既可以定义HTML,JS,CSS等静态内容,还可以定义Java代码的动态内容
3>JSP = HTML + Java
(2)第一个JSP文件
1>导入依赖
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
2>创建JSP文件
3>编写HTML和Java代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>你好jsp</h1>
<%
System.out.println("你好jsp");
%>
</body>
</html>
(3)JSP原理
********jsp本质上就是个Servlet
原理:JSP在被访问时,由于JSP容器(Tomcat)将其转换成Java文件(Servlet),在由JSP容器(tomcat)将其编译,最终对外提供服务的其实就是这个.java的字节码文件
(4)JSP脚本
1>用于定义java代码
2>分类
实际上在tomcat把JSP文件转换成对应的Servlet的字节码文件后,这个.java文件里面有一个方法叫做Service(),相当于我们java程序的主方法,而这个Service()在这个Servlet的类里面,结构大概为:(伪代码)
public class *****Service implment *****{
void service(){
out.print(”*****“)//字符输出流
}
}
1.<%......%>:内容会放在service()方法里
相当于,在主方法里写代码
2.<%=....%>:内容会放到out.print()中,作为它的参数
相当于用字符输出流在网页输出字符串
3.<%!.....%>:内容会放在service()方法之外,被类直接包含
相当于定义全局变量和全局函数
实例:
<%--
Created by IntelliJ IDEA.
User: 86132
Date: 2022/5/13
Time: 18:25
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>
<h1>你好jsp</h1>
<%
System.out.println("你好jsp");
String a = "wangrongxiao";
String login = login();
%>
<%=
a+login
%>
<%!
String login(){
return "你好,我是全局函数";
}
%>
</body>
</html>
效果:
(5)EL表达式
1.获取数据,并且存储到request域里面。
2.把数据转发到想要传送的jsp文件里
3.在jsp文件里写${}在域中查对应key的数据
<1>和<2>
List<Brand> brands = new ArrayList<Brand>();
brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
// 把数据放到Request域里
request.setAttribute("Brand",brands);
// 数据转发到jsp
request.getRequestDispatcher("/a.jsp").forward(request,response);
<3>
若是不显示,<body>上加
<%@ page isELIgnored="false"%>
<body>
<%--关键代码--%>
${Brand}
</body>
结果演示:访问servlet
(6)JSTL标签
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
1.
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2.if标签
3.
4.普通for循环