您的位置:首页 > 编程语言 > Java开发

Javaweb之JSP入门

2017-09-03 01:05 246 查看

JSP入门

1. JSP概述

1.1 什么是JSP

JSP(Java Server Pages)是JavaWeb服务器的动态资源,它与html页面的作用相同,显示数据和获取数据。

1.2 JSP的组成

JSP由JSP指令,Java代码片段(脚本)和JSP动作标签组成。

注意:当pageEncoding为ISO-8859-1时,代表当前jsp文件的编码格式为ISO-8859-1,因为该编码不支持中文,所以保存不了。因此必须把编码格式改为gbk或utf-8(一般使用utf-8格式编码)。可以在myeclipse中修改默认的jsp编码格式,方法参照如下http://www.cnblogs.com/xdp-gacl/p/3496161.html

2. JSP语法

2.1 JSP脚本(java代码片段)

JSP 脚本就是java代码片段,它分为三种:

* <% …%> Java语句;

* <%= %> 在浏览器中输出java代码运算的结果,例如:

<%=3+5 %> ; <%5>6 %> ; <%=true&false%> ; <%=b=100>89?a=true:a=false %>

* <%!…%> Java定义成员(成员变量,成员方法);

2.2 内置对象out

out对象在JSP页面中无需创建即可使用,作用是向客户端输出。

其中<%= %>与out.print()功能是相同的,都是向客户端输出,例如

<%=s1 %>和 <% out.print(s1)%>

2.3 多个<%.. %>可以通用

案例:循环打印表格

<table border="1px" width="%60">
<tr>
<th>序号</th>
<th>用户名</th>
</tr>
<% for(int i = 1;i<=10;i++){ %>
<tr>
<td><%=x></td>
<td>user<%=x%></td>
</tr>
<%}%>
</table>


3.JSP原理

3.1 JSP是特殊的Servlet

当JSP页面首次被访问时,容器(tomcat)会先把JSP编译成java文件,然后再去执行java文件。所以JSP就是一个java类文件。



3.2 JSP的java文件存放位置

E:\javaExplore\apache-tomcat-7.0.77\work\Catalina\localhost\myapp\org\apache\jsp\JspDemo

Jsp中所有静态信息(html的标签内容)会通过out.write完成打印!

这些静态信息都是作为字符串输出给客户端的。

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {

final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
}


仔细观察代码后会发现,JSP文件就是一个Servlet,拥有init(),destory()和service()方法。而在jsp页面中写的代码,会相应的存在service()方法中。

4.JSP的<%! %>

作用: <%!…%> 写java中的成员(成员变量,成员方法)

<body>
<%! private String name="张三";
public String test(){
return "李四";
}
%>
<%=name %>
</br>
<%out.print(test()); %>
</body>


查看JSP编译后的文件发现,以上添加的代码会相应的变为成员变量和成员方法!

5.JSP中的注释

Jsp注释<%– … –%>

可以在jsp中使用html注释
<!--   -->
,但是该注释的结果还是会在浏览器查看器中显示,如果想让某条代码在jsp中不被编译且显示,应该使用jsp注释



6.JSP指令

6.1 JSP指令概述

JSP指令:<%@指令名 attr1=”1” attr2=”2” %>,一般会放在JSP文件的最上方。

<%@ page language=”java” import=”java.util.*” pageEncoding=”ISO-8859-1”%>

JSP 中有三大指令,page,include,taglib,最为常用是page

6.2 page指令

page指令是最为常用的指令,也是属性最多的指令

page指令没有必须属性。都是可选属性,例如<%@page %>.

在JSP页面中,任何指令都可以重复出现

<%@ page language=”java” %>

<%@ page import=”java.util.*” %>

<%@ page pageEncoding=”ISO-8859-1”%>

6.2.1 page指令的pageEncoding和contentType(重点)

pageEncoding指定当前JSP页面的编码!这个编码是给服务器看的,服务器需要知道当前JSP文件使用的编码,不然服务器无法正确把JSP编译成java文件。所以这个编码一定需要与真实的页面编码一致即可!在MyEclipse中,在JSP文件上点击右键,选择属性就可以看到当前JSP页面的编码了。

contentType属性与response.setContentType()方法的作用相同!它会完成两项工作,一是设置响应字符流的编码,二是设置content-type响应头。例如:<%@ contentType=”text/html;charset=utf-8”%>,它会使jsp的java文件中出现response.setContentType(“text/html;charset=utf-8”)。

无论是page指令的pageEncoding还是contentType,它们的默认值都是ISO-8859-1,我们知道ISO-8859-1是无法显示中文的,所以JSP页面中存在中文的话,一定要设置这两个属性。

其实pageEncoding和contentType这两个属性的关系很“暧昧”:

* 当设置了pageEncoding,而没设置contentType时: contentType的默认值为pageEncoding;

* 当设置了contentType,而没设置pageEncoding时: pageEncoding的默认值是contentType;

也就是说,当pageEncoding和contentType只出现一个时,那么另一个的值与出现的值相同。如果两个都不出现,那么两个属性的值都是ISO-8859-1。所以通过我们至少设置它们两个其中一个!

6.2.2 page指令的import属性

import是page指令中一个很特别的属性!

import属性值对应编译后的java文件中中的import语句。

import属性值可以使逗号:
<%@page import=”java.net.*,java.util.*,java.sql.*”%>


import属性是唯一可以重复出现的属性:

<%@page import=”java.util.” import=”java.net.” import=”java.sql.*”%>

但是,我们一般会使用多个page指令来导入多个包:

<%@ page import=”java.util.*”%>

<%@ page import=”java.net.*”%>

<%@ page import=”java.text.*”%>

6.2.3 page指令的errorPage和isErrorPage

一个JSP页面出错后,Tomcat会响应给用户错误信息(500页面)!如果你不希望Tomcat给用户输出错误信息,那么可以使用page指令的errorPage来指定错误页!也就是自定义错误页面,例如:<%@page errorPage=”error.jsp”%>。这时,在当前JSP页面出现错误时,会请求转发到error.jsp页面。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@page errorPage="error.jsp"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'errorDemo1.jsp' starting page</title>
</head>
<body>
<%
int val=5/0;//该句会出现代码错误
%>
欢迎光临
</body>
</html>


在上面代码中,errorDemo1.jsp抛出异常后,会请求转发到error.jsp。在浏览器的地址栏中还是errorDemo1.jsp,因为是请求转发!

而且客户端浏览器收到的响应码为200,表示请求成功!如果希望客户端得到500,那么需要指定error.jsp为错误页面。

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ page  isErrorPage="true" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'error.jsp' starting page</title>
</head>

<body>
This is my error page. <br>
</body>
</html>


  注意,当isErrorPage为true时,说明当前JSP为错误页面,即专门处理错误的页面。那么这个页面中就可以使用一个内置对象exception了。其他页面是不能使用这个内置对象的!

温馨提示:IE会在状态码为500时,并且响应正文的长度小于等于512B时不给予显示!而是显示“网站无法显示该页面”字样。这时你只需要添加一些响应内容即可,例如上例中的error.jsp中我给出一些内容,IE就可以正常显示了!

6.2.4 web.xml中配置错误页面

不只可以通过JSP的page指令来配置错误页面,还可以在web.xml文件中指定错误页面。这种方式其实与page指令无关。

web.xml

<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error500.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/error.jsp</location>
</error-page>


<error-page>
有两种使用方式:

*
<error-code>
<location>
子元素;

*
<exception-type>
<location>
子元素;

  其中
<error-code>
是指定响应码;
<location>
指定转发的页面;
<exception-type>
是指定抛出的异常类型。

在上例中:

* 当出现404时,会跳转到error404.jsp页面;

* 当出现RuntimeException异常时,会跳转到error.jsp页面;

* 当出现非RuntimeException的异常时,会跳转到error500.jsp页面。

  

这种方式会在控制台看到异常信息!而使用page指令时不会在控制台打印异常信息。

6.2.5 page指令的isELIgnored

6.2.6 page指令其他属性

Language:JSP只能转为java文件

session: 默认为true,表示当前JSP页面可以支持session对象,如果为false,表示当前JSP不能使用session对象

注意:我们page指令还有其他的一些属性,但是不常用

6.3 include指令

Include 指令表示静态包含!即把多个JSP合并成一个JSP文件
Include 指令只有一个属性:file,指定要包含的jsp页面,例如

6.4 taglib指令

这个指令需要学习自定义标签后才会使用。
在JSP页面中使用第三方的标签库时,需要使用taglib指令来“导包”。例如:

7.JSP九大内置对象

内置对象:即在jsp页面中可以直接使用的已经存在的对象,不需要我们去创建

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {

final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
}


还有一个内置对象是exception,只有页面设置为<%@ page isErrorPage=”true” %>才可以使用

exception对象,这个对象不常用。

重点:pageContext内置对象

7.1 pageContext的内置对象

在javaWeb中一共有四大域对象,其中Servlet中可以使用request、session、servletContext (在JSP中application内置对象),而在JSP中可以使用request、session、application (servletContext),pageContext(今天的重点)。

pageContext对象是属于 javax.servlet.jsp.PageContext 类,它的主要功能如下:

* 域对象功能;

* 代理其他域对象功能;

* 获取其他内置对象;

7.1.1 域对象功能

pageContext也是域对象(范围是当前页面,是四个域对象中可活动区域最小的)

(1) void setAttribute(String name,Object value);

(2) object getAttribute(String name);

(3) void removeAttribute(String name);

7.1.2 代理其他域对象功能

还可以使用pageContext来代理其它3个与对戏那个的功能,也就是说可以使用pageContext向request,session,application对象中存取数据。

(1) void setAtrribute(String name,Object value,int scope);在指定范围内添加参数

(2) Object getAttribute(String name,int scope);获取指定范围的数据

(3) void removeAttribute(String name,int scope);移除指定范围的数据

(4) Object findAttribute(String name):依次在page、request、session、application范围内查找名称为name的参数。如果找到就立即停止,这说明在这个范围内有相同名称的参数,那么page范围的优先级最高!

pageContext.setAttribute(“x1”,”x”);
pageContext.setAttribute(“x2”,”xx”,PageContext.REQUEST_SCOPE);
pageContext.setAttribute(“x3”,”xxx”,PageContext.SESSION_SCOPE);
pageContext.setAttribute(“x4”,”xxxx”,PageContext.APPLICATION_SCOPE);


在test1.jsp中测试pageContext

<body>

<h3>使用pageContext设置域参</h3>
<%
pageContext.setAttribute("x1", "x");
pageContext.setAttribute("x2", "xx", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("x3", "xxx", PageContext.SESSION_SCOPE);
pageContext.setAttribute("x4", "xxxx", PageContext.APPLICATION_SCOPE);

pageContext.setAttribute("x5", "pageContext聂小倩");
pageContext.setAttribute("x5", "request聂小倩",PageContext.SESSION_SCOPE);
%>

<%
String x1=(String)pageContext.getAttribute("x1");
String x2=(String)pageContext.getAttribute("x2", PageContext.REQUEST_SCOPE);
String x3=(String)pageContext.findAttribute("x3");
String x4=(String)pageContext.findAttribute("x4");
String x5=(String)pageContext.findAttribute("x5");

out.println("x1="+x1);
out.println("x2="+x2);
out.println("x3="+x3);
out.println("x4="+x4);
out.println("x5="+x5);
%>
</body>


在test2.jsp中测试

<body>
<%
String x1=(String)pageContext.getAttribute("x1");
String x2=(String)pageContext.getAttribute("x2", PageContext.REQUEST_SCOPE);
String x3=(String)pageContext.findAttribute("x3");
String x4=(String)pageContext.findAttribute("x4");
String x5=(String)pageContext.findAttribute("x5");

out.println("x1="+x1);  //null
out.println("x2="+x2);  //null
out.println("x3="+x3);  //xxx
out.println("x4="+x4);  //xxxx
out.println("x5="+x5);  //request聂小倩
%>


7.1.3 获取其他内置对象

一个pageContext对象等同于所有内置对象,即1个当9个,这是因为可以使用pagecontext对象获取其它8个内置对象

* JspWriter getOut() :获取out内置对象

* ServletConfig getServletConfig(): 获取config内置对象

* Object getPage():获取page内置对象

* HttpServletRequest getRequest():获取request内置对象

* HttpServletResponse getResponse():获取response内置对象

* HttpSession getSession():获取session内置对象

* ServletContext getServletContext():获取application内置对象

* Exception getException():获取exception内置对象。

<body>
<h3>测试pageContext获取内置对象</h3>
*   JspWriter getOut()  :获取out内置对象</br>
*   ServletConfig getServletConfig():   获取config内置对象</br>
*   Object getPage():获取page内置对象</br>
*   HttpServletRequest getRequest():获取request内置对象</br>
*   HttpServletResponse getResponse():获取response内置对象</br>
*   HttpSession getSession():获取session内置对象</br>
*   ServletContext getServletContext():获取application内置对象</br>
*   Exception getException():获取exception内置对象。</br>
<hr>
<h3>获取对象</h3>
<%
pageContext.getOut().print("通过pageContext获取了out内置对象并输出本句!");
%>
</br>
<%
out.print("通过pageContext获取ServletConfig对象并获取初始化参数"
+pageContext.getServletConfig().getInitParameter("user1"));
%>
</br>
<%
out.print("通过pageContext获取page对象并获取类加载器"
+pageContext.getPage().getClass().getClassLoader());
%>
</br>
<%
out.print("通过pageContext获取request对象并获取ip地址"
+pageContext.getRequest().getLocalAddr());
%>
</br>
<%
out.print("通过pageContext获取response对象并获取编码格式"
+pageContext.getResponse().getContentType());
%>
</br>
<%
out.print("通过pageContext获取session对象并获取session的数据"
+pageContext.getSession().getAttribute("x5"));
%>
</br>
<%
out.print("通过pageContext获取servletContext对象并工程名称"
+pageContext.getServletContext().getContextPath());
%>
</br>
</body>


8.JSP动作标签

8.1 jsp动作标签概述

动作标签的作用是用来简化我们的Java脚本。

JSP的动作标签是JavaWeb内置的标签,他们是已经被定义好的,直接拿来用就行

一些常用JSP动作标签。如果觉得不够用,我们可以自己定义。

JSP动作标签的格式

8.2
<jsp:include>

<jsp:include>
标签的作用是用来包含其他jsp页面!但是该动作标签和<%@include file=””%>实现的级别不同。

Include指令:实在编译时完成的包含。即把当前jsp和被包含的jsp合并成一个JSP后在编译成java文件

include标签:实在运行时完成的包含,即当前JSP和被包含的JSP都会各自生成的各自Servlet,然后执行当前jsp的Servlet时完成包含另外的一个Servlet。



8.3
<jsp:forward/>

Forward 标签的作用是请求转发,与RequestDispatcthe forward()方法相同

<body>
<h2>a.jsp</h2>
<jsp:forward page="b.jsp"/>
</body>


转发到

<%page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>This is b.jsp</title>
</head>
<body>
<h3>这里是b.jsp</h3>
</body>
</html>


8.4
<jsp:param>

还可以在
<jsp:include/>
<jsp:forward/>
标签中使用
<jsp:param>
子标签,它的作用是用来传递参数的,下面演示:

9.JSP与JavaBean相关的动作标签

9.1 什么是Javabean?

JavaBean是一种规范,也是对类的要求,它要求Java类的成员变量提供getter/setter方法,这些成员变量称之为javaBean的属性。

JavaBean还要求类必须提供仅有的无参构造。例如:

package com.ibeifeng.javaBean;

public class User {
private String username;
private String password;

public User() {
super();
}

public User(String username, String password) {
super();
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}


9.2 JavaBean的属性

JavaBean具有getter/setter方法的成员变量

* 也可以只提供getter()方法,这样的属性叫做只读属性

* 也可以只提供setter()方法,这样的属性叫做只写属性

* 如果属性的类型为boolean,那么读方法的格式可以是get或is。例如boolean a;

那么a属性的读方法可以写为getA() 也可以是isA()

注意:其实javaBean还有其它的一些规范,暂不列出。

9.3 在jsp中与javaBean相关的动作标签

9.3.1
<jsp:useBean>

在当前的JSP页面中创建JavaBean的对象。

把创建的JavaBean对象存放在域对象那个中。

<h3>使用jsp标签创建对象</h3>
<jsp:useBean id="userj1" class="com.ibeifeng.javaBean.User" />


上面的代码表示在当前JSP页面中创建USER对象,并且保存在pageContext域中。上面的语句可以翻译成一下两句

<h3>使用java代码创建对象</h3>
<%
com.ibeifeng.javaBean.User user1=new com.ibeifeng.javaBean.User();
pageContext.setAttribute("user1", user1);
%>


9.3.2
<jsp:setProperty> <jsp:getProperty>

标签的作用就是给JavaBean设置属性值,而的作用是获取对象中属性的值,在使用它们之前需要先创建javaBean

<h3>使用jsp标签创建对象</h3>
<jsp:useBean id="userj1" class="com.ibeifeng.javaBean.User" />

<h3>设置值</h3>
<jsp:setProperty name="userj1" property="username" value="admin"/>
<jsp:setProperty name="userj1" property="password" value="123"/>

<h3>获取值</h3>
<jsp:getProperty name="userj1" property="username"/>
<jsp:getProperty name="userj1" property="password"/>


9.4 commons-beanutils

commons-beanutils是一个工具类,有两个jar包构成

* commons-beanutils.jar

* common-logging.jar

(1)表单

<form action="/day06_08/beanutilsServlet">
用户编号:<input name="id" type="text">  </br>
用户姓名:<input name="username" type="text"> </br>
登录密码:<input name="password" type="text"> </br>
用户性别:<input name="sex" type="text"> </br>
用户年龄:<input name="age" type="text"> </br>
用户住址:<input name="address" type="text"> </br>

<input type="submit" value="提交注册">
</form>


(2)JavaBean:User

public class User {
private String id;
private String username;
private String password;
private String sex;
private String age;
private String address;

public User() {
super();
}

public User(String id, String username, String password, String sex,
String age, String address) {
super();
this.id = id;
this.username = username;
this.password = password;
this.sex = sex;
this.age = age;
this.address = address;
}

public String getId() {
return id;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public String getSex() {
return sex;
}

public String getAge() {
return age;
}

public String getAddress() {
return address;
}

public void setId(String id) {
this.id = id;
}

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

public void setSex(String sex) {
this.sex = sex;
}

public void setAge(String age) {
this.age = age;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="+ password + ", sex=" + sex + ", age=" + age + ", address="+ address + "]";
}
}


(3)将前台的数据封装到对象中

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//目的:将前端传送过来的数据,封装到User的一个对象中。因为我们以后的数据库会用到
/*User user1=new User();
String id=request.getParameter("id");
user1.setId(id);*/

//使用commons-beanutils工具完成
Map<String,String[]> map=request.getParameterMap();
User user=new User();

try {
BeanUtils.populate(user, map);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(user);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: