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

Java之JSP和Servlet基础知识。

2016-06-24 01:06 766 查看

JSP基础

JSP起源

JSP,Java Server Pager的简称。由SUN倡导并联合其它公司创建。

JSP是一门脚本语言

JSP可以嵌入到HTML中

JSP拥有Java语言的所有特性

面向对象、健壮、多线程、安全、可移植、高性能

JSP运行于JSP容器中

Tomcat、Jetty等。

JSP会被转换成Servlet

JSP->Servlet->Class文件。

Mac下常用shell命令:

pwd 打印当前目录

ls 列出当前目录下的所有文件目录

cd 更改目录

.代表当前工作目录

..代表上一级目录

~代表用户根目录

chmod更改权限

JSP基本语法

<%   %>
JSP代码段,可以输入任意的Java语言片段。

<%!  %>
JSP声明,在JSP页面范围声明变量、函数和类。

<%=  %>
JSP表达式

JSP中HTML注释:

<!-- -->
<!-- <% %>-->


<%-- --%>
JSP注释,不会被客户端浏览器看到。

JSP编译指令

通知Servlet引擎处理消息,它只在JSP程序被转化成Servlet的过程中起作用。

Page指令

在JSP最上方,用于指定语言,MIME,编码,错误跳转页面等等。

1. contentType指定MIME和网页编码,无859.

2. import导入多个java类,也可以使用多个page导入多个java类。

3. errorPage表示JSP页面发生运行时错误跳转的页面。

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.ArrayList,java.util.LinkedList"
errorPage="err.jsp"%>


include指令

静态包含指令,可将外部文件包含进来。包含JSP文件时,不能有重复的变量声明。

被导入的JSP编译指令会起作用。

<%@ include file="header.jsp"%>


taglib指令

JSP动作指令

客户端请求时动态执行的指令

forward指令

重定向指令,它下面的代码不会被执行,不会被返回到客户端。

可以通过jsp:param指令向跳转的JSP页面传递参数。在目标JSP页面中通过request.getParameter()方法接收参数。

<jsp:forward page="err.jsp">
<jsp:param name="name" value="bendeng"></jsp:param>
<jsp:param name="pass" value="8765432"></jsp:param>
</jsp:forward>


include指令

动态包含指令,包含静态HTML和动态JSP文件。

被导入的JSP编译指令不会起作用,并可以额外加参数。

<jsp:include page="body.jsp">
<jsp:param name="bgcolor" value="red"></jsp:param>
</jsp:include>


在被包含的JSP文件中通过request对象将body背景色修改为传过去的值。

<body bgcolor="<%=request.getParameter("bgcolor")%></body>


useBean指令

JavaBean:一个公开的构造函数、属性有get、set方法、可序列化。

例如:我们在接收提交的页面的,使用User这个bean,然后使用useBean指令配合setProperty、getProperty指令来接收显示提交内容:

提交页面如下:

<form action="regist.jsp" method="post">
用户名:<input type="text" name="name"/><br>
密码:<input type="password" name="pass"/><br>
<input type="submit" value="提交"/>


接受页面如下:

<jsp:useBean id="user" class="com.ben.bean.User"></jsp:useBean>
<jsp:setProperty property="name" name="user"></jsp:setProperty>
<jsp:setProperty property="pass" name="user"></jsp:setProperty>

<jsp:getProperty property="name" name="user"></jsp:getProperty>
<jsp:getProperty property="pass" name="user"></jsp:getProperty>


JSP内置对象

out对象

向客户端浏览器输出信息

<%
out.println("out对象");
out.newLine();
out.println("<br>");
out.flush();
out.clearBuffer();//清空缓冲区的数据
//out.clear();//也是清空缓冲区数据,不同的是如果之前调用flush,则会抛出异常。
out.println("缓冲区大小:" + out.getBufferSize());//默认8K,可通过编译指令修改,如:<%@ page buffer="16kb" %>
out.println("<br>");
out.println("当前缓冲区剩余大小:" + out.getRemaining());
%>


request对象

request对象封装了客户端提交到服务器的请求信息,表单、cookie等信息。

请求的方法名:<%=request.getMethod() %><br/>//GET
请求的资源:<%=request.getRequestURI() %><br/>
请求使用的协议:<%=request.getProtocol() %><br/>//HTTP/1.1
请求的服务器IP:<%=request.getServerName() %><br/>
请求的服务器端口:<%=request.getServerPort() %><br/>
客户端的IP地址:<%=request.getRemoteAddr() %><br/>
客户端的主机名:<%=request.getRemoteHost() %><br/>
getRequestURL:<%=request.getRequestURL() %><br/>
getScheme:<%=request.getScheme() %>//Http

//request.getParameter()  用于从客户端请求获取表单信息

request.setAttribute();
request.getAttribute();
这两个方法用于在web组件间共享信息,比如JSP之间。

请求头信息;
<%
Enumeration<String> e = request.getHeaderNames();
while(e.hasMoreElements()){
String headerName = e.nextElement();
out.println(headerName+":"+request.getHeader(headerName)+"<br/>");
}
%>


response对象

对客户端请求封装回复信息。

response.setHeader("Cache-Control", "no-cache");//浏览器读到这个头信息,就不会将网页信息存到缓存。还有public,private等
response.setIntHeader("Refresh", 2);//每隔2秒刷新一次
//response.sendRedirect("index.jsp");//重定向到另一个JSP网页
//设置Cookie
Cookie cookie = new Cookie("ben","deng");
cookie.setMaxAge(3600);//单位为s
response.addCookie(cookie);


session对象

HTTP是无状态的。服务器使用session可以保存客户端浏览器的信息。

<%! SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); %>
sessionId= <%=session.getId() %></br>
session创建时间= <%=sdf.format(new Date(session.getCreationTime())) %></br>
session最后访问时间= <%=sdf.format(new Date(session.getLastAccessedTime())) %></br>
session失效时间: <%= session.getMaxInactiveInterval()%>//默认1800s


session失效时间可以通过修改部署描述符来实现。

<session-config>
<session-timeout>10</session-timeout>
</session-config>


如果不生效,需要删掉work目录的文件。

application对象

应用一启动就会生成application对象。web应用不关闭,application就一直存在。

servlet的环境通过调用
getServletConfig().getContext()
方法获得。作用域是application(整个程序运行期)。它提供了关于服务器版本,应用级初始化参数和应用内资源绝对路径,注册信息的方式。

服务器信息:<%=application.getServerInfo() %>
应用信息:<%=application.getServletContextName() %>
主机信息:<%=application.getVirtualServerName() %>


由于Application对象是随应用的生命周期存在,所以通过它可以对一些配置进行全局加载和存储。

config对象

代表当前JSP程序的配置信息。一般JSP在应用中作为View层使用,一般使用较少,在Servlet中用的比较多。读取的配置信息来自web.xml。

<%=config.getInitParameter("name") %>


在web.xml中配置一个servlet:

<servlet>
<servlet-name>config</servlet-name>
<jsp-file>/jsp/config.jsp</jsp-file>
<init-param>
<param-name>name</param-name>
<param-value>name</param-value>
</init-param>
<init-param>
<param-name>pass</param-name>
<param-value>pass</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>config</servlet-name>
<url-pattern>/*</url-pattern><!--这个样式所有请求都会返回config.jsp的内容 -->
</servlet-mapping>


在config.jsp中,使用

String name = config.getInitParameter("name");
String pass = config.getInitParameter("pass");


取出配置在web.xml中的信息。

exception对象

exception对象只有在page指令中具有属性
isErrorPage="true"
时才有效。它就是Java中普通的Throwable对象。

通过JSP错误页面中一个catch块已经益出但没有捕获的java.lang.Throwable的任意实例,传向了errorPage的URI。

比如在indx.jsp中运行如下代码

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"
errorPage="exception.jsp"%>
try{
int c = 3/0;
}catch(Exception e){

}


在exception.jsp中:

<%
out.print(exception.getLocalizedMessage());
%>


页面输出
/ by zero


page对象

继承自Object对象,代表当前JSP页面。

pageContext对象。

pageContext对象提供所有四个作用域层次的属性查询和修改能力,它也提供了转发请求到其它资源和包含其他资源的方法。该对象的方法都是抽象方法。

JSP作用域

作用域规定的是变量的有效期限。JSP有四大作用域:Request、Page、Session、Application。

我们使用
public Object getAttribute(String name)
获得变量值,

使用
public void setAttribute(String name, Object value)
将变量值保存到对应作用域中。

对象说明类型作用域
request请求对象javax.servlet.ServletRequestRequest
response响应对象javax.servlet.SrvletResponsePage
pageContext页面上下文对象javax.servlet.jsp.PageContextPage
session会话对象javax.servlet.http.HttpSessionSession
application应用程序对象javax.servlet.ServletContextApplication
out输出对象javax.servlet.jsp.JspWriterPage
config配置对象javax.servlet.ServletConfigPage
page页面对象javax.lang.ObjectPage
exception异常对象javax.lang.Throwablepage
如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。

从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。

  

如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。

所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。

如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。

所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。

如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。

整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。

application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。

与上述三个不同的是,application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,session都是完全隔离的,无论如何修改都不会影响其他人的数据。

初识Servlet

Servlet = Server + Applet。它是一个特殊的Java类。

下面新建一个Servlet:

public class Hello extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doGet(req, resp);
PrintWriter pw = resp.getWriter();
pw.println("Hello Servlet");
pw.close();
}

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

@Override
public void init() throws ServletException {
System.out.println("hello init()");
super.init();
}

@Override
public void destroy() {
System.out.println("hello destroy()");
super.destroy();
}
}


在web.xml中进行配置:

<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.ben.servlet.Hello</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>


使用tomcat,进行运行。localhost:8080/hello,即可显示Hello Servlet。我是在IDEAIU中进行的,如果在Eclipse中路径可能有变化,需要加工程名。

如果浏览器出现HTTP Status 405 - HTTP method GET is not supported by this URL,注释掉doGet和doPost的父类调用即可。

Servlet处理流程



客户端浏览器发出一个请求,tomcat内置web Server接收到请求,将请求转达给Servlet容器,Servlet容器会加载Servlet实例。Servlet使用HttpServletRequest接收请求实例,Servlet可能会将请求转发给其它的Servlet处理。全部处理完,请求结果通过HttpServletResponse对象返回给浏览器。

当Servlet装载和实例化以后,Servlet会调用
init()
方法,进行初始化。Servlet处于服务状态。在整个生命周期中,init()执行一次。接收请求时,会调用
service()
方法,当Servlet不再使用,容器销毁Servlet之前会调用
destroy()
方法。destroy()方法中做一些资源释放和日志输出的操作。

init()不需要重载,只在需要初始化时做一些操作时才需要重载,建议重载无参的init()方法,不用调用super.init()方法,有参的init()必须调用父类的init()方法。

使用Servlet实现简单的登陆

login.jsp如下:

<form method="post" action="<%=request.getContextPath()%>/login">
<input name="username" type="text" placeholder="用户名"/><br/>
<input name="password" type="password" placeholder="密码"/><br/>
<input type="submit" value="登陆">
<input type="reset" value="重置">
</form>


新建一个LoginServlet:

public class LoginServlet extends HttpServlet {

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");

//System.out.println("用户名=" + username);
//System.out.println("密码=" + password);

String forward = null;
//这里简单判断用户名来跳转成功和失败页面
if("ben.deng".equals(username)){
forward = "success.jsp";
//这种跳转不会带请求的参数信息,只在响应头中的location中指定了跳转页面。但可以进入其他应用的页面
//resp.sendRedirect("success.jsp");
}else{
forward = "fail.jsp";
//resp.sendRedirect("fail.jsp");
}
//请求转发,可以请求参数带给转发的页面。但只限于应用内的页面。
RequestDispatcher dispatcher = req.getRequestDispatcher(forward);
dispatcher.forward(req,resp);
}

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

@Override
public void init() throws ServletException {
System.out.println("login init()");
}
}


web.xml配置:

<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.ben.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>


Servlet过滤器

创建一个过滤器:

public class MyFilter implements Filter {

public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("doFilter...");
chain.doFilter(req, resp);
}

public void init(FilterConfig config) throws ServletException {
System.out.println("filter init():" + config.getInitParameter("paramKey"));
}

}


和Servlet一样,需要在web.xml中配置:

<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.ben.filter.MyFilter</filter-class>
<init-param>
<param-name>paramKey</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


在一个web应用中,可以有多个Filter,多个Filter的执行顺序是和web.xml中配置的顺序是一致的。

过滤器之编码转换

在doGet或doPost方法中返回一串有中文的字符串,浏览器很多时候会显示乱码。这时我们可以在过滤器中进行处理。

String charEncoding = "UTF-8";
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
if(!charEncoding.equals(req.getCharacterEncoding())){
req.setCharacterEncoding(charEncoding);
}
resp.setCharacterEncoding(charEncoding);
chain.doFilter(req, resp);
}


过滤器之权限校验

新建一个权限校验过滤器:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
String loginStatus = (String) request.getSession().getAttribute("login");
if (loginStatus != null && "success".equals(loginStatus)) {
chain.doFilter(req, resp);
} else {
String reqPath = request.getServletPath();
if (!reqPath.contains("login")) {
//System.out.println("您尚未登陆");
RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
rd.forward(req, resp);
}else{
chain.doFilter(req, resp);
}
}
}


在部署描述符中注册过滤器:

<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.ben.filter.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


上述代码示例中是将登陆成功后再session中设置一个login属性为success,在其他非login/login.jsp等页面中判断是否有这个session,没有或值不对(比如登录失败设置的其他值),则要求跳转到登录界面。从而实现一个简单的权限校验过滤。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: