JavaWeb——【JSP】——一篇文章带你入门JSP,值得你一看!

17 篇文章 0 订阅

JSP


1.概述

在动态网页开发中,经常需要动态生成HTML内容,例如,一篇新闻报道的测览次数需要动态生成。这时,如果使用 Servlet 来实现 HTML 页面数据的改变,需要调用大量的输出语句,从而使静态内容和动态内容混合在一起,导致程序非常臃肿。为了克服 Servlet 的这些缺点,Oracle(Sun)公司推出了JSP技术。

1.1.什么是JSP

JSP全名是 Java Server Page,它是建立在 Servlet 规范之上的动态网页开发技术。
在JSP文件中,HTML代码与Java代码共同存在,其中,HTML代码用来实现网页中静态内容的显示,Java代码用来实现网页中动态内容的显示。为了与普通HTML有所区别JSP文件的扩展名为.jsp

2.JSP快速了解

2.1.Servlet 输出 HTML

public class HtmlServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<h1>Hello World</h1>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

2.2.创建JSP界面

创建新的项目,然后再项目的WebContent目录下新建simple.jsp文件,如下
eclipse 提供了新建jsp界面的功能,在WebContent目录右键,New-JSP File
在这里插入图片描述
新建好界面后,在 节点里面添加如下代码:
在这里插入图片描述
访问jsp界面,其中输出了时间信息,其中每次查看时间都不同,会显示当前时间,这是因为simple.jsp是一个动态网页,它的效果实际上是有服务器程序实现的。
在这里插入图片描述

2.3.分析JSP所生成的Servlet代码

当用户第一次访问JSP页面时,该页面都会被 JspServlet 翻译成一个 Servlet 源文件,然后将源文件编译为 .class 文件。 Servlet 源文件和 .class 文件都放在硬盘\Workspace\eclipse.metadata.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\Things\org\apache\jsp
每个人的可能在有点稍许不同,有的work目录是在tmp2,也可能有多个tmp0和tmp1,所以这个可以根据个人情况查找。
在这里插入图片描述
idea的web项目不是直接将webapp放在tomcat容器中。而是将生成的webapp与tomcat按照idea的“技术”形成连接
具体路径为:注意需要给项目设置项目名开头的访问路径
C:\Users\登录名.IntelliJIdea2017.2\system\tomcat\Tomcat-pure_工程名\work\Catalina\localhost\appcontext名称\org\apache\jsp

3.JSP基本语法(掌握)

JSP界面可以按照编写 HTML 的方式来编写其中可以包含 HTML 文件的所有静态内容,在静态的HTML内容之中可以嵌套JSP的其它各种元素来产生动态内容和执行业务逻辑,JSP页面中的静态HTML内容被称为JSP模板元素,JSP模板元素定义了网页的基本骨架,即定义了页面的结构和外观。

3.1.JSP表达式

JSP表达式用于将程序数据输出到客户端
语法
<%= %>
将=号后面的变量或者表达式计算结果转成一个字符串,然后插入JSP页面输出结果的相应位置处,如刚刚编写的代码
<%=new Date().toLocaleString() %>

3.2.JSP脚本片段

JSP脚本片段是值嵌套在<% 和 %>之中的一条或者多条Java程序代码,这些Java程序代码必须严格遵守Java语法规范,否则编译会报错。

简单的脚本片段

<%
	int x = 10;
	out.print(x);
%>

分开写,单个脚本中的语句可以是不完整的,但是多个脚本片段组合后的结果必须是完整的Java语句

<%
	int y = 20;
%>
<%
	out.print(y);
%>

3.3.JSP声明

JSP脚本片段编写的代码都被放到了一个叫_jspService()的方法里面,变量成为了局部变量,
有时候我们希望定义的变量是成员变量,这时就可以使用JSP声明。

JSP声明中定义的都是成员方法、成员变量、静态方法、静态属性、静态代码块

语法
<%!
	java代码
%>

在这里插入图片描述

3.4.JSP注释

<%--这是注释内容--%>
需要注意的是:JSP页面中格式为<%-- 注释信息 --%> 内容不会发布到客户端

4.JSP指令(了解)

为了设置JSP页面中的一些信息,Sum公司提供了JSP指令
page、include、taglib三种指令

4.1.page指令

在JSP页面中,经常需要对页面的某些特性进行描述,例如,页面的编码方式,JSP页面采用的语言等,这时,可以通过page指令来实现

常用属性

格式:
<%@ page 属性名1= “属性值1” 属性名2= “属性值2” …%>

常用属性如下:

  • language:jsp脚本中可以嵌入的语言种类
  • pageEncoding:当前jsp文件的本身编码
  • contentType:response.setContentType(text/html;charset=UTF-8)
  • import:指定JSP页面翻译成Servlet资源文件中导入的包或者类
  • session:是否jsp在翻译时自动创建session
  • errorPage:当当前页面出错后跳转到哪个页面
  • isErrorPage:当前页面是一个处理错误的页面

4.2.include指令

有时候,需要在JSP页面静态包含一个文件,例如HTML文件、文本文件等,这时,可以通过 include指令来实现

语法
<%@ include file="被包含的文件地址"%>

5.JSP隐式对象(掌握)

在JSP页面中,有一些对象需要频繁使用,如果每次创建这些对象则会非常麻烦,为此,JSP提供了9个隐式对象,它们是JSP默认创建的,可以直接在JSP页面使用,例如刚开始演示的out对象

名称类型描述
outjavax.servlet.jsp.JspWriter用于页面输出
Requestjavax.servlet.http.HttpServletRequest得到用户请求信息,
Responsejavax.servlet.http.HttpServletResponse服务器向客户端的回应信息
Configjavax.servlet.ServletConfig服务器配置,可以取得初始化参数
Sessionjavax.servlet.http.HttpSession用来保存用户的信息
Applicationjavax.servlet.ServletContext所有用户的共享信息
Pagejava.lang.Object指当前页面转换后的Servlet类的实例
pageContextjavax.servlet.jsp.PageContextJSP的页面容器
Exceptionjava.lang.Throwable表示JSP页面所发生的异常,在错误页中才起作用
5.1.1.out对象

在JSP页面中,经常需要向客户端发送文本内容,这时,可以使用out对象来实现

使用示例

<%
	out.print(new java.util.Date().toLocaleString());
	response.getWriter().println("使用response对象输出");
%>
5.1.2.pageContext对象
5.1.2.1.pageContext获取隐式对象

在JSP中,想要获取JSP隐式对象,可以使用pageContext对象,pageContext对象时Javax.servlet.jsp.PageContext类的实例对象,它代表当前JSP页面的运行环境,并提供了一些列用于获取其他隐式对象的方法。

方法功能
JspWriter getOut()获取out隐式对象
Object getPage()获取page隐式对象
ServletRequest getRequest()获取request隐式对象
ServletResponse getResponse( )获取response隐式对象
HttpSession getSession( )获取session隐式对象
ServletConfig getServletConfig( )获取config
ServletContext getServletContext( )获取application隐式对象
Exception getException()获取exception隐式对象

示例,使用pageContext获取request对象

<%
	HttpServletRequest httpServletRequest = (HttpServletRequest) pageContext.getRequest();
	String ip = request.getRemoteAddr();
	out.print(ip);
%>
5.1.2.2.pageContext操作属性
方法名功能
void setAttribute(String name, Object value, int scope)设置pageContext对象的属性
Object getAttribute(String name, int scope)获取pageContext对象的属性
void removeAttribute(String name,int scope)删除指定范围内名称为name的属性
void removeAttribute(String name)删除所有范围内名称为name的属性
Object findAttribute(String name)从4个域对象中查找名称为name的属性

pageContext对象的作用范围有4个值

  • pageContext.PAGE_SCOPE:表示页面范围
  • pageContext.REQUEST_SCOPE:表示请求范围
  • pageContext.SESSION_SCOPE:表示会话范围
  • pageContext.APPLICATION_SCOPE:表示Web应用程序范围

使用findAttribute()方法来查找属性是,会依次从page、request、session、application的顺序进行查找,找到立刻返回实际的值,找不到返回null。

示例

<%
	pageContext.setAttribute("company", "jf", pageContext.PAGE_SCOPE);
	Object name = pageContext.getAttribute("company", pageContext.PAGE_SCOPE);
	out.print("公司名称为:" + name);
%>
5.1.3.JSP四个域范围
PageContext常量名描述作用域名称域对象类型
PageScope当前页面中有效pageContextPageContext
RequestScope一次请求范围RequestHttpServletRequest
Sessionscope一次会话范围SessionHttpSession
Applicationscope应用范围ApplicationServletContext
  • page:表示当前页,通常没用。jsp标签底层使用
  • request:表示一次请求。通常一次请求就一个页面,但如果使用请求转发,可以涉及多个页面。
  • session:表示一次会话。可以在多次请求之间共享数据
  • application:表示一个web应用(项目)。可以整个web项目共享,多次会话共享数据

6.JSP标签(了解)

JSP标签元素用来控制JSP的行为,执行一些常用的JSP页面动作。通过标签元素可以实现使用多行Java代码能够实现的效果,如包含页面文件,实现请求转发等

6.1.jsp:include标签

在JSP页面中,为了把其他资源的输出内容插入到当前JSP页面的输出内容中,JSP技术提供了jsp:include标签
语法:
<jsp:include page="relativeURL" flush=”true|false”>
page属性用于指定被引入资源的相对路径, flush属性用于指定是否将当前页面的输出内容刷新到客户端,默认情况下,fush属性的值为 false

使用示例
在项目下新建两个jsp,分别是included.jsp和dynamicInclude.jsp,其中dynamicInclude.jsp引入了included.jsp

included.jsp

<body>
	<% Thread.sleep(5000);%>
	included.jsp 中的内容;
</body>

dynamicInclude.jsp

<body>
	dynamicInclude.jsp 中的内容
	<jsp:include page="included.jsp" flush="true" />
</body>

启动 Tomcat服务器,访问地址,发现浏览器首先会显示 dynamicInclude jsp页面中的输出内容,等待5秒后,才会显示 included jsp页面的输出内容。说明被引用的资源 included jsp在当前JSP页面输出内容后才被调用,显示结果如下
在这里插入图片描述

注意:虽然include指令和jsp:include标签都能够包含一个文件,但是它们4之间有很大的区别:
< jsp:include>标签中要引入的资源和当前 JSP 页面是两个彼此独立的执行实体,即被动态引入的资源必须能够被Web容器独立执行。而 include 指令只能引入遵循JSP格式的文件,被引入文件与当前JSP文件需要共同合并才能翻译成一个 Servlet 源文件
<jsp:include>标签中引入的资源是在运行时才包含的,而且只包含运行结果。而 include指令引入的资源是在编译时期包含的,包含的是源代码
<jsp:include>标签运行原理与 RequestDispatcher.include()方法类似,即被包含的页面不能改变响应状态码或者设置响应头,而 include指令没有这方面的限制。

6.2.jsp:forward标签

在JSP页面中,经常需要将请求转发给另外一个资源,这时,除了 RequestDispatcher 接口的 forward() 方法可以实现外,还可以通过<jsp:forward>标签来实现,<jsp:forward>标签的具体语法格式如下所示:
<jsp:forward page="relativeURL" />
page属性用于指定请求转发到的资源的相对路径,该路径是相对于当前的JSP页面的URL

jspforward.jsp

<body>
	<jsp:forward page="welcome.jsp" />
</body>

welcome.jsp

<body>
	你好欢迎访问,当前的时间是
	<% out.print(new java.util.Date()); %>>
</body>

显示结果
在这里插入图片描述

7.案例

7.1.显示列表

添加ListServlet,使用循环生成列表需要的数据,并添加到集合中

public class ListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ArrayList<Message> messages = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Message m = new Message();
            m.setId(i);
            m.setTitle("标题" + i);
            m.setContent("内容" + i);
            messages.add(m);
        }
        req.setAttribute("messages",messages);
        req.getRequestDispatcher("/list.jsp").forward(req,resp);
    }
}

添加list.jsp,获取到request域中的数据,使用循环进行显示

<table border="1" width="600px" align="center">
    <%
        ArrayList<Message> messages = (ArrayList<Message>) request.getAttribute("messages");
        if (messages != null) {
            for (int i = 0; i < messages.size(); i++) {
    %>
        <tr>
            <td align="center"><%=messages.get(i).getTitle() %></td>
            <td align="center"><%=messages.get(i).getContent()%></td>
        </tr>
    <%
            }
        }
    %>
</table>

7.2.图片验证码

使用jsp完成图片验证码的功能

<%@page import="javax.imageio.ImageIO"%>
<%@page import="java.awt.Font"%>
<%@page import="java.awt.Graphics"%>
<%@page import="java.awt.image.BufferedImage"%>
<%@page import="java.util.Random"%>
<%@page import="java.awt.Color"%>
<%@ page language="java" contentType="image/JPEG; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%!
    //获取随机颜色  
    Color getRandColor(int fc,int bc){
        Random random = new Random();
        if(fc>255) fc=255;
        if(bc>255) bc=255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r,g,b);
    }
%>
<%
    //设置页面不缓存
    response.setHeader("Pragma", "No-cache");
    response.setHeader("Cache-Control", "no-cache");
    response.setDateHeader("Expires", 0);
    //在内存中创建图像
    int width = 60;
    int height = 20;
    BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    //获取图形上下文
    Graphics g = image.getGraphics();
    //随机类
    Random random = new Random();
    //设定背景
    g.setColor(getRandColor(200, 250));
    g.fillRect(0, 0, width, height);
    //设定字体
    g.setFont(new Font("Times New Roman",Font.PLAIN,18));
    //随机产生干扰线
    g.setColor(getRandColor(160, 200));
    for (int i = 0; i < 100; i++) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(12);
        int yl = random.nextInt(12);
        g.drawLine(x, y, x + xl, y + yl);
    }
    //随机产生4位验证码
    String[] codes = {"2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"};
    String code = "";
    for(int i=0;i<4;i++){
        String str = codes[random.nextInt(codes.length)];
        code += str;
        // 将认证码显示到图象中
        g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
        //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
        g.drawString(str, 13 * i + 6, 16);
    }
    // 将认证码存入SESSION
    session.setAttribute("code", code);
    // 图象生效
    g.dispose();
    // 输出图象到页面
    ImageIO.write(image, "JPEG", response.getOutputStream());
    //加上下面代码,运行时才不会出现java.lang.IllegalStateException: getOutputStream() has already been called ..........等异常
    response.getOutputStream().flush();
    response.getOutputStream().close();
    response.flushBuffer();
    out.clear();
    out = pageContext.pushBody();
%>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狮子座的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值