JSP

 

1 JSP

    1. JSP概念

JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它 [1]  是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML标准通用标记语言的子集)文件(*.htm,*.html)中插入Java程序段(Scriptlet)JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp) JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。

它实现了Html语法中的java扩展(以 <%, %>形式)。JSPServlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。

JSP技术使用Java编程语言编写类XMLtagsscriptlets,来封装产生动态网页的处理逻辑。网页还能通过tagsscriptlets访问存在于服务端的资源的应用逻辑。JSP将网页逻辑与网页设计的显示分离,支持可重用的基于组件的设计,使基于Web的应用程序的开发变得迅速和容易。 JSP(JavaServer Pages)是一种动态页面技术,它的主要目的是将表示逻辑从Servlet中分离出来。

Java ServletJSP的技术基础,而且大型的Web应用程序的开发需要Java ServletJSP配合才能完成。JSP具备了Java技术的简单易用,完全的面向对象,具有平台无关性且安全可靠,主要面向因特网的所有特点。

 

    1. JSP的组成

[1]创建一个JSP

在webContent目录下右键-新建-jspFile

②将一个HTML文件修改为JSP文件

把HTML文件打开 -- 

在HTML文件的第一行添加一个JSP的指令

<%@ page language="java" contentType="text/html; charset=utf-8"

pageEncoding="utf-8"%>

把HTML文件的后缀修改为jsp

完事!

[2]JSP的组成

①指令  <%@ xxxx %>   JSP页面一共有三大指令(page,incloud,taglib)

*Page 是指令名称.

*Language 此页面使用的脚本语言。目前为止JSP的动态脚本只有java。

ContentType  配置页面的内容类型

pageEncoding 配置页面的编码

import 配置页面应该导入的java包。

。。。。其他属性用到再说。

Page指令就是标明此页面为一个JSP页面,其中的属性配置了页面的相关配置

②静态内容

③小脚本  <% java code %>

④表达式  <%=表达式/变量 %>

表达式的作用是将表达式的结果输出到页面上。

⑤JSP注释 <%-- JSP的注释 --%>

JSP的注释仅仅存在于JSP页面的源代码中,在翻译,和编译之后的程序中都是不存在的,更不可能存在于运行过程。所以在JSP页面尽量使用JSP注释。

⑥申明 <%! 申明成员变量或者方法 %>

测试在JSP小脚本中申明方法:

小脚本中无法申明方法。

通过申明<%! %>申明方法:

⑦JSP动作 <jsp:activeName >

[3]使用JSP动态生成一个列表页面

①创建实体类

public class User {

    private int id;

    private String name;

    private int age;

    private int gender;

  //setget方法省略

}

②添加JSP页面 userList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ page import="java.util.*,com.igeek.webcore.pojo.*" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>用户列表</title>

<!-- boostrap需要的所有的css -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap.min.css'>

<!-- 主题CSS -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css'>

<script type='text/javascript' src='js/jquery-2.1.0.min.js'></script>

<script type='text/javascript'

    src='js/bootstrap-3.3.7-dist/js/bootstrap.min.js'></script>

</head>

<%

    //创建一个用户列表

    List<User> users = new ArrayList<User>();

    users.add(new User(1,"张三丰",18,1));

    users.add(new User(2,"卡卡西",18,2));

    users.add(new User(3,"卡卡东",18,2));

    users.add(new User(4,"雷锋",18,1));

    users.add(new User(5,"路飞",18,1));

%>

<body>

    <table class="table">

       <tr>

           <th>#</th>

           <th>姓名</th>

           <th>性别</th>

           <th>年龄</th>

           <th>操作</th>

       </tr>

       <%

           for(int i = 0;i<users.size();i++){

              User u = users.get(i);

       %>

       <tr>

           <td><%=u.getId() %></td><td><%=u.getName() %></td>

           <td><%=u.getAge() %></td><td><%=u.getGender()==1?"":"" %></td>

           <td>

              <a href="inputEdit?userId=<%=u.getId() %>">编辑</a>/

              <a href="javascript:delete(<%=u.getId() %>)">删除</a>

           </td>

       </tr>

       <%} %>

    </table>

</body>

</html>

测试效果:

1.3JSP的执行过程

[1]JSP是服务器端的页面,是否可以像HTML一样通过浏览器执行。

Java代码实际上没有被发送到客户端。原因是浏览器根本就无法解释运行java代码。所以浏览器根本不可能直接运行jsp。

[2]JSP被翻译成java文件

在tomcat的work目录中查找JSP生成的java文件

Login.jsp生成的java文件的申明

再观察:

发现:编写的JSP文件生成的java代码继承了HttpJspBase,而HttpJspBase继承HttpSerlvet。也就是说我们编写JSP生成的java文件就是一个servlet。

结论:JSP文件最终会被tomcat翻译成servlet。然后在编译servlet,再运行。

[3]JSP中的组成部分被翻译成java代码后的内容

在生成的代码中有方法:相当于HttpServlet中的service方法

  • 静态内容被输出

  • Java小脚本 不做任何翻译。

  • 表达式会使用out.print输出 

  • JSP的注释,不做任何翻译,也不会出现在java代码中。
  • 申明  <%!  %>  会被翻译成成员变量或者方法

为什么不能在小脚本中申明方法?

因为小脚本的程序最终会被放在_jspService方法内部,在方法内部当然不能再申明方法。

  • JSP动作, 会调用专门的程序实现动作。

  • JSP指令  会根据不同的指令进行不同的处理

 

1.4JSP可以配置在web.xml文件中

由于JSP最终也是被翻译成servlet所以JSP可以代替servlet,在web.xml文件中配置。

将servlet-class使用jspfile代替配置JSP的位置。

实际可能产生的情况:

通常情况下我们会将JSP放在WEB-INF中

访问:404

WEB-INF 和 META-INF目录下的任何内容都不能直接方法。

 

在web.xml文件中配置访问该JSP的url

测试:

  1. JSP内置对象

2.1什么是内置对象

所谓JSP的内置对象就类似于JS的内置对象window一样,不需要申明,不需要创建,就可以直接在页面中使用。比如:

修改login.jsp中的form的action

添加object.jsp,在 jsp中通过request获取请求参数

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>JSP内置对象</title>

</head>

<body>

<%

    //通过request获取请求参数

    String uname = request.getParameter("uname");

    String upass = request.getParameter("upass");

%>

用户名:<%=uname %><br/>

密码:<%=upass %>

</body>

</html>

测试结果:

在这个案例中object.jsp中的代码中的request对象没有申明,没有创建,就可以直接使用

request就是内置对象。

看内幕:在JSP页面的申明中request是不能直接使用。

查看JSP生产的源代码:

我们在小脚本中编写所有的java代码最终都会被翻译到_jspService方法中,而此方法的申明是:

所有的内置对象都是在_jspService方法的开始就申明好了,所以可以直接使用。

可是这里只有8个内置对象,还有一个呢?

还有一个是exception对象,只有将页面配置为错误页面时,才有此对象:

Error.jsp生成的java代码:

2.2九大内置对象

[1]request对象

Request对象是service的方法的参数。封装了所有的请求信息。

请求JSP就相当于请求了servlet,所以和servlet中的request是一个意思。

获取请求参数

和请求参数相关的API不再多说。

GetRequestURI();获取请求的uri

[2]response对象

response对象是service的方法的参数。提供了各种响应客户端的API。

设置响应头。

获取响应的流。

重定向。

[3]session对象

代表一个会话。

HTTP协议是无状态的。所谓状态就是不记录当前访问状态。也就是连续的刷新网页进行多次请求,服务器端并不知道是同一个客户端在请求。 

实际你见过的状态都是被记录的。就是因为使用了session。

当客户单第一次请求服务器时,创建session,存储在服务器端,将sessionId返回给客户端。客户端进行第二次访问时会携带sessionId。服务器根据携带的sessionId找到对应的session。才能知道和上一次是同一客户端访问的。当浏览器关闭之后,浏览器缓存中的sessionId会消失,当再次访问时session会被重新创建。 当持续半小时(session的默认存活时间)没有对服务器进行访问时,服务器会销毁session。再访问时必须重新创建session。

Session的获取方式:

Session的类型是HttpSession。

[4]Application对象

Applicatiopn对象的类型是ServletContext

一个应用程序就只有一个application对象。在所有的页面中的application对象都是同一个对象。

[5] pageContext对象

pageContext对象的类型是:PageContext

此对象的主要作用就是获取其他内置对象

是page作用域中的操作对象

[6] config对象

Config对象的类型是ServletConfig

Config对象主要就是获取初始化参数。

配置初始化参数:

在页面获取:

[7]out对象

Out对象的类型是:JspWriter

jspWriter和PrintWriter是兄弟类。有同样的功能。

主要作用就是在网页中输出对应的数据。

主要API

Writ(..)

Print(..)

[8]page对象

Page对象的类型是Object

Page对象代表当前页面本身。

[9]exception对象

Exception对象的类型是Throwable。

此对象只有在page指令中的属性isErrorPage配置为true的时候才有该对象,该对象包含了所有的错误信息。

测试:

创建error.jsp

将page指令中的isErrorPage配置为true.

在页面可以使用exception对象输出错误信息。

将其他页面的page指令中的errorPage = “error.jsp”

当其他页面出错时就会进入error.jsp,并且将错误信息存储到exception对象中。

  1. JSP的4个作用域

Page < request < session <application

[1]page作用域

Page作用域中对应一个对象:pageContext。

pageContext中的和作用域相关的API

(1)给page作用设置加属性

pageContext.setAttribute(String key,Object value);

(2)获取page作用域中的属性值

pageContext.getAttribute(String key);

(3)删除page作用域中的属性值

pageContext.removeAttribute(String key);

 

所谓作用域就是相当于一个存储的空间。类似于map。可以存储各种类型数据。但是才空间只能在指定的范围内使用。

 

所谓page作用域就是page范围内的存储空间。 Page范围指的就是一个页面内。

比如:

<%

    //page作用域设置一个属性

    pageContext.setAttribute("pageAttr", "igeek-pageAttrValue");

%>

<p>这里有很多代码,请脑补!</p>

<%

    //获取page作用域中的属性值

    Object pageAtrr = pageContext.getAttribute("pageAttr");

    //输出

    out.print(pageAtrr);

    //重新修改

    pageContext.setAttribute("pageAttr", "igeek-pageAttrValue-update");

%>

<p>这里有很多代码,请脑补!</p>

<%

    //再获取page作用域中的属性值

    pageAtrr = pageContext.getAttribute("pageAttr");

    //输出

    out.print(pageAtrr);

    //删除page作用域中的属性

    pageContext.removeAttribute("pageAttr");

%>

<p>这里有很多代码,请脑补!</p>

<%

    //再获取page作用域中的属性值

    pageAtrr = pageContext.getAttribute("pageAttr");

    //输出

    out.print(pageAtrr);

%>

页面效果:

Tips:在A页面中设置的属性,在B页面时无法获取的。

[2]request作用域

request作用域中对应一个对象:request。

request中的和作用域相关的API

(1)给page作用设置加属性

request.setAttribute(String key,Object value);

(2)获取page作用域中的属性值

request.getAttribute(String key);

(3)删除page作用域中的属性值

request.removeAttribute(String key);

 

request作用域中的对象request的操作作用域的API和pageContext是一样的,只是作用域的范围不一样。

Request作用域的意思是,一次请求中。

什么是一次请求?

客户端发送请求到服务器端响应完成称之为一次请求。

案例:

访问FirstServlet,执行了first和second两个servlet,响应客户端的是secondServlet的响应内容。  所以是一次请求,所以firstServlet和SecondServlet是共享request作用域中的数据的。

注意:这个案例中可以使用两个jsp或者jsp和servlet混合使用。

完全可以在serlvet中调用service读取数据,添加到request的作用域中,然后转发到jsp,再在jsp中从request作用域中取出显示。

4使用JSP和servlet完成一个简单的案例

[1]修改添加功能和登录功能

添加成功进入登录页面,添加失败返回添加页面,并且提示添加失败。

  1. 将添加的html修改为JSP
  2. 修改registServlet。

C.修改添加页面  可以显示错误提示信息

D.修改login.html为login.jsp

E.修改loginServlet实现登录失败是的提醒

F.修改登录页面,显示错误信息

[2]修改列表功能

A.添加一个accountList.jsp

在JSP中从request中取出用户列表信息,循环显示在页面上。

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ page import="com.igeek.pojo.*,java.util.*"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>账户列表</title>

<!-- boostrap需要的所有的css -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap.min.css'>

<!-- 主题CSS -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css'>

<script type='text/javascript' src='js/jquery-2.1.0.min.js'></script>

<script type='text/javascript'

    src='js/bootstrap-3.3.7-dist/js/bootstrap.min.js'></script>

<script type="text/javascript" src="js/ck/account.js"></script>

</head>

<body>

    <%

       //request中取出数据

       Object obj = request.getAttribute("accounts");

       if (obj == null) {

           //重定向到accountList servlet

           response.sendRedirect("accountList");

           return;

       }

       List<Account> accounts = (List<Account>) obj;

    %>

    <table class="table table-bordered">

       <tr>

           <th>#</th>

           <th>账户名</th>

           <th>登录名</th>

           <th>电话</th>

           <th>邮箱</th>

           <th>创建时间</th>

           <th>操作</th>

       </tr>

       <%

           for(Account a :accounts){

       %>

       <tr>

           <td><%=a.getAccountId() %></td>

           <td><%=a.getAccountName() %></td>

           <td><%=a.getLoginName() %></td>

           <td><%=a.getAccountTel() %></td>

           <td><%=a.getAccountEmail() %></td>

           <td><%=a.getCreateTime() %></td>

           <td>

              <A href="inputEdit?accountId=<%=a.getAccountId() %>">编辑</A>/

              <A href="deleteAccount(<%=a.getAccountId() %>)">删除</A>

           </td>

       </tr>

       <%} %>

    </table>

</body>

</html>

C.修改accountListServlet

package com.igeek.servlet;

 

import java.io.IOException;

import java.io.PrintWriter;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import com.igeek.pojo.Account;

import com.igeek.service.AccountService;

 

/**

 * Servlet implementation class AccountListServlet

 */

public class AccountListServlet extends HttpServlet {

         private static final long serialVersionUID = 1L;

      

         private AccountService accountService = new AccountService();

 

         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   //查询所有的账户,响应账户列表

                   List<Account> accounts = accountService.queryAll();

                   //将查询到的集合设置为request作用域的属性

                   request.setAttribute("accounts", accounts);

                   //转发到accountList.jsp

                   request.getRequestDispatcher("accountList.jsp").forward(request, response);

         }

 

         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   //调用自己的doGet方法。   无论是get请求还是post请求,都是同样的处理方式。

                   this.doGet(request, response);

         }

}

[3]修改编辑功能

A.添加一个编辑的jsp

在页面一开始的时候从request中取出要编辑的账户对象,然后将对象的数据通过value属性设置到对应的表单域中。

不要忘记添加一个隐藏域用来设置账户的编号。

<%@ page language="java"  contentType="text/html; charset=utf-8"

    pageEncoding="utf-8"%>

    <%@ page import="com.igeek.pojo.*,java.util.*"%>

<!DOCTYPE html>

<html>

<head>

<meta charset='utf-8' />

<title>添加账户</title>

<!-- boostrap需要的所有的css -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap.min.css'>

<!-- 主题CSS -->

<link rel='stylesheet' type='text/css'

    href='js/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css'>

<script type='text/javascript' src='js/jquery-2.1.0.min.js'></script>

<script type='text/javascript'

    src='js/bootstrap-3.3.7-dist/js/bootstrap.min.js'></script>

 

</head>

<body>

    <div style="text-align:center;"><h1 style="margin-left:auto;margin-right:auto;">编辑账户</h1></div>

    <%

       //request中取出要编辑的账户对象

       Object obj = request.getAttribute("editAccount");

       if(obj==null){

           //重定向到列表页面

           response.sendRedirect("accountList");

           return;

       }

       Account a = (Account)obj;

       //request取出错误信息

       Object errorMsg = request.getAttribute("editError");

       //判断是否有错误信息

       if(errorMsg!=null){

    %>

    <div style="text-align:center; color:red"><%=errorMsg %></div>

    <%} %>

    <form class='form-horizontal' method='post' action='edit'>

       <input type="hidden" name="accountId" value="<%=a.getAccountId() %>"/>

       <div class='form-group'>

           <label for='inputEmail3' class='col-sm-2 control-label'>用户名</label>

           <div class='col-sm-10'>

              <input type='text' value="<%=a.getAccountName() %>" style='width: 500px;' class='form-control'

                  name='username' placeholder='用户名' id='username'> <span

                  style='display: none; color: red;' id='usernamespan'>*用户名不能为空</span>

              <span style='display: none; color: red;' id='namespan'>*用户名已存在</span>

              <!-- <input type='text' value='用户名不能为空' /> -->

           </div>

       </div>

       <div class='form-group'>

           <label for='inputEmail3' class='col-sm-2 control-label'>登录名</label>

           <div class='col-sm-10'>

              <input type='text' value="<%=a.getLoginName() %>" style='width: 500px;' class='form-control'

                  name='loginName' placeholder='登录名' id='loginname'> <span

                  style='display: none; color: red;' id='loginnamespan'>*登录名不能为空</span>

           </div>

       </div>

       <div class='form-group'>

           <label for='inputEmail3' class='col-sm-2 control-label'>密码</label>

           <div class='col-sm-10'>

              <input type='password'  style='width: 500px;' class='form-control'

                  name='password' placeholder='密码' id='password'> <span

                  style='display: none; color: red;' id='passwordspan'>*密码必须由数字字母下划线组成</span>

           </div>

       </div>

       <div class='form-group'>

           <label for='inputEmail3' class='col-sm-2 control-label'>确认密码</label>

           <div class='col-sm-10'>

              <input type='password' style='width: 500px;' class='form-control'

                  name='repassword' placeholder='确认密码' id='repassword'> <span

                  style='display: none; color: red;' id='repasswordspan'>*两次输入的密码不一致</span>

           </div>

       </div>

       <div class='form-group'>

           <label for='inputPassword3' class='col-sm-2 control-label'>邮箱</label>

           <div class='col-sm-10'>

              <input type='email' value="<%=a.getAccountEmail() %>" style='width: 500px;' class='form-control'

                  name='email' placeholder='邮箱' id='email'> <span

                  style='display: none; color: red;' id='emailspan'>*请输入正确的邮箱格式</span>

           </div>

       </div>

       <div class='form-group'>

           <label for='inputPassword3' class='col-sm-2 control-label'>电话</label>

           <div class='col-sm-10'>

              <input type='text' value="<%=a.getAccountTel() %>" style='width: 500px;' class='form-control'

                  name='tel' placeholder='电话' id='tel'> <span

                  style='display: none; color: red;' id='telspan'>*请输入正确的电话格式</span>

           </div>

       </div>

       <div class='form-group'>

           <label class='col-sm-2 control-label'>性别</label>

           <input type='radio' <%=a.getAccountGender()==1?"checked":"" %>

              style='margin-left: 30px;' name='gender' value='1'> <input

              type='radio' style='margin-left: 30px;' <%=a.getAccountGender()==2?"checked":"" %> name='gender' value='2'>

           <input type='radio' style='margin-left: 30px;' name='gender'

              value='0' <%=a.getAccountGender()==0?"checked":"" %>  >保密

       </div>

       <div class='form-group'>

           <label for='inputPassword3' class='col-sm-2 control-label'>备注</label>

           <div class='col-sm-10'>

              <textarea class='form-control' style='width: 500px;' name='mark'

                  placeholder='备注'><%=a.getAccountMark() %></textarea>

           </div>

       </div>

       <div class='form-group'>

           <div class='col-sm-offset-2 col-sm-10'>

              <div class='checkbox'>

                  <label> <input type='checkbox'> Remember me

                  </label>

              </div>

           </div>

       </div>

       <div class='form-group'>

           <div class='col-sm-offset-2 col-sm-10'>

              <button type='submit' class='btn btn-default'

                  id='sub'>注册</button>

           </div>

       </div>

    </form>

</body>

</html>

 

B.修改inputEditServlet

package com.igeek.servlet;

 

import java.io.IOException;

import java.io.PrintWriter;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import com.igeek.pojo.Account;

import com.igeek.service.AccountService;

 

/**

 * Servlet implementation class InputEditServlet

 */

public class InputEditServlet extends HttpServlet {

         private static final long serialVersionUID = 1L;

         private AccountService accountService = new AccountService();

         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   //根据客户端传递的账户id查询账户信息

                   int accountId = 0;

                   try {

                            accountId = Integer.parseInt(request.getParameter("accountId"));

                   } catch (NumberFormatException e) {

                   }

                   //查询account对象

                   Account a = accountService.queryById(accountId);

                   //将查询的账户添加到request的作用域中

                   request.setAttribute("editAccount", a);

                   //转发到编辑页面

                   request.getRequestDispatcher("editAccount.jsp").forward(request, response);

         }

 

         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   doGet(request, response);

         }

 

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值