首页 > 编程知识 正文

清单3包含表单页面的jsp代码,JSP表单

时间:2023-12-26 12:11:38 阅读:322667 作者:FHVH

本文目录一览:

编写一个JSP页面,该页面提供一个表单,用户通过表单输入半径提交后,JSP页面将计算圆的周长与面积的任务

1、新建一个JSP页面,写一个Form,在这个Form中写一个文本框用于接收用户输入的半径,在写一个提交按钮

2、新建一个Servlet,用于接受上一个JSP的请求,在Servlet中获取提交的参数——半径,然后完成计算,将计算结果放在Request中,然后转发到另一个JSP

3、新建一个JSP页面,用于显示结果。获取request中的计算结果并显示

求jsp代码,题目如下:

rect.jsp

%@ page language="java" pageEncoding="utf-8"%

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

html

head

/head

body

form action="com.jsp" method="post"

请输入正方形的边长: input type="text" name="length" width="100px"

br/ br/

input type="submit" value="submit"

/form

/body

/html

com.jsp

%@ page language="java" pageEncoding="utf-8"%

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

html

head

/head

body

%

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

float s=0;

try{

s=Float.parseFloat(length);

}

catch (Exception e)

{

out.print("请输入有效数值brbr");

s=0;

}

%

正方形周长为: %=4*s %br/

正方形面积为: %=s*s %br/

/body

/html

JSP 页面跳转问题 求助

每个表单里都设置一个隐藏域,取相同的名字不同的值,在R.jsp里String hid=request.getParameter("param")取得隐藏域的值,hid.equals("")作为条件

或者表单的action="R.jsp?param=a/b/c",R.jsp里同上取参数

假设需要编写一个JSP页面input.jsp,该页面提供一个表单。。。 来JAVA大神

input.jsp:

form action="show.jsp" method="post"

    用户名:input type="text" name="userName" /br/

    密码:input type="password" name="password" /br/

    电子邮箱:input type="text" name="email" /br/

    地址:input type="text" name="address" /br/

    input type="submit" value="提交" /

/form

show.jsp:

%

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

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

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

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

    

    out.print("用户名:" + userName);

    out.print("br/");

    out.print("密码:" + password);

    out.print("br/");

    out.print("邮箱:" + email);

    out.print("br/");

    out.print("地址:" + address);

    out.print("br/");

%

jsp页面的代码

Vector v=(Vector)application.getAttribute("Mess");//这行代码是声明一个Vector 变量,此变量是一个键值对象

其他的太 多了不想写

如何避免logout后,后退按钮依旧显示缓存的有关问题

 JSP示例

为了更为有效地阐述实现方案,本文将从展示一个示例应用logoutSampleJSP1中碰到的问题开始。这个示例代表了许多没有正确解决退出过程的Web应用。logoutSampleJSP1包含了下述jsp页面:login.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中页面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不允许未经认证的用户访问的,也就是说,这些页面包含了重要信息,在用户登陆之前或者退出之后都不应该出现在浏览器中。login.jsp包含了用于用户输入用户名和密码的form。logout.jsp页包含了要求用户确认是否退出的form。loginAction.jsp和logoutAction.jsp作为控制器分别包含了登陆和退出代码。

第二个示例应用logoutSampleJSP2展示了如何解决示例logoutSampleJSP1中的问题。然而,第二个应用自身也是有疑问的。在特定的情况下,退出问题还是会出现。

第三个示例应用logoutSampleJSP3在第二个示例上进行了改进,比较完善地解决了退出问题。

最后一个示例logoutSampleStruts展示了Struts如何优美地解决登陆问题。

注意:本文所附示例在最新版本的Microsoft Internet Explorer (IE), Netscape Navigator, Mozilla, FireFox和Avant浏览器上测试通过。

Login action

Brian Pontarelli的经典文章《J2EE Security: Container Versus Custom》讨论了不同的J2EE认证途径。文章同时指出,HTTP协议和基于form的认证并未提供处理用户退出的机制。因此,解决途径便是引入自定义的安全实现机制。

自定义的安全认证机制普遍采用的方法是从form中获得用户输入的认证信息,然后到诸如LDAP (lightweight directory access protocol)或关系数据库的安全域中进行认证。如果用户提供的认证信息是有效的,登陆动作往HttpSession对象中注入某个对象。HttpSession存在着注入的对象则表示用户已经登陆。为了方便读者理解,本文所附的示例只往HttpSession中写入一个用户名以表明用户已经登陆。清单1是从loginAction.jsp页面中节选的一段代码以此阐述登陆动作:

Listing 1

//...

//initialize RequestDispatcher object; set forward to home page by default

RequestDispatcher rd = request.getRequestDispatcher("home.jsp");

//Prepare connection and statement

rs = stmt.executeQuery("select password from USER where userName = '" + userName + "'");

if (rs.next()) {

 //Query only returns 1 record in the result set; only 1

 password per userName which is also the primary key

 if (rs.getString("password").equals(password)) { //If valid password

session.setAttribute("User", userName); //Saves username string in the session object

 }

 else { //Password does not match, i.e., invalid user password

request.setAttribute("Error", "Invalid password.");

rd = request.getRequestDispatcher("login.jsp");

 }

} //No record in the result set, i.e., invalid username

else {

 request.setAttribute("Error", "Invalid user name.");

 rd = request.getRequestDispatcher("login.jsp");

}

}

//As a controller, loginAction.jsp finally either forwards to "login.jsp" or "home.jsp"

rd.forward(request, response);

//...

本文所附示例均以关系型数据库作为安全域,但本文所阐述的观点对任何类型的安全域都是适用的。

Logout action

退出动作就包含了简单的删除用户名以及对用户的HttpSession对象调用invalidate()方法。清单2是从loginoutAction.jsp页面中节选的一段代码以此阐述退出动作:

Listing 2

//...

session.removeAttribute("User");

session.invalidate();

//...

阻止未经认证访问受保护的JSP页面

从form中获取用户提交的认证信息并经过验证后,登陆动作简单地往 HttpSession对象中写入一个用户名,退出动作则做相反的工作,它从用户的HttpSession对象中删除用户名并调用invalidate()方法销毁HttpSession。为了使登陆和退出动作真正发挥作用,所有受保护的JSP页面都应该首先验证HttpSession中是否包含了用户名以确认当前用户是否已经登陆。如果HttpSession中包含了用户名,也就是说用户已经登陆,Web应用则将剩余的JSP页发送给浏览器,否则,JSP页将跳转到登陆页login.jsp。页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp均包含清单3中的代码段:

Listing 3

//...

String userName = (String) session.getAttribute("User");

if (null == userName) {

 request.setAttribute("Error", "Session has ended. Please login.");

 RequestDispatcher rd = request.getRequestDispatcher("login.jsp");

 rd.forward(request, response);

}

//...

//Allow the rest of the dynamic content in this JSP to be served to the browser

//...

在这个代码段中,程序从HttpSession中减缩username字符串。如果字符串为空,Web应用则自动中止执行当前页面并跳转到登陆页,同时给出Session has ended. Please log in.的提示;如果不为空,Web应用则继续执行,也就是把剩余的页面提供给用户。

运行logoutSampleJSP1

运行logoutSampleJSP1将会出现如下几种情形:

1) 如果用户没有登陆,Web应用将会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的执行,也就是说,假如用户在浏览器地址栏中直接敲入受保护JSP页的地址试图访问,Web应用将自动跳转到登陆页并提示Session has ended.Please log in.

2) 同样的,当一个用户已经退出,Web应用也会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的执行

3) 用户退出后,如果点击浏览器上的后退按钮,Web应用将不能正确保护受保护的页面——在Session销毁后(用户退出)受保护的JSP页重新在浏览器中显示出来。然而,如果用户点击返回页面上的任何链接,Web应用将会跳转到登陆页面并提示Session has ended.Please log in.

阻止浏览器缓存

上述问题的根源在于大部分浏览器都有一个后退按钮。当点击后退按钮时,默认情况下浏览器不是从Web服务器上重新获取页面,而是从浏览器缓存中载入页面。基于Java的Web应用并未限制这一功能,在基于PHP、ASP和.NET的Web应用中也同样存在这一问题。

在用户点击后退按钮后,浏览器到服务器再从服务器到浏览器这样通常意思上的HTTP回路并没有建立,仅仅只是用户,浏览器和缓存进行了交互。所以,即使包含了清单3上的代码来保护JSP页面,当点击后退按钮时,这些代码是不会执行的。

缓存的好坏,真是仁者见仁智者见智。缓存的确提供了一些便利,但通常只在使用静态的HTML页面或基于图形或影响的页面你才能感受到。而另一方面,Web应用通常是基于数据的,数据通常是频繁更改的。与从缓存中读取并显示过期的数据相比,提供最新的数据才是更重要的!

幸运的是,HTTP头信息“Expires”和“Cache-Control”为应用程序服务器提供了一个控制浏览器和代理服务器上缓存的机制。HTTP头信息Expires告诉代理服务器它的缓存页面何时将过期。HTTP1.1规范中新定义的头信息Cache-Control可以通知浏览器不缓存任何页面。当点击后退按钮时,浏览器重新访问服务器已获取页面。如下是使用Cache-Control的基本方法:

1) no-cache:强制缓存从服务器上获取新的页面

2) no-store: 在任何环境下缓存不保存任何页面

HTTP1.0规范中的Pragma:no-cache等同于HTTP1.1规范中的Cache-Control:no-cache,同样可以包含在头信息中。

通过使用HTTP头信息的cache控制,第二个示例应用logoutSampleJSP2解决了logoutSampleJSP1的问题。logoutSampleJSP2与logoutSampleJSP1不同表现在如下代码段中,这一代码段加入进所有受保护的页面中:

//...

response.setHeader("Cache-Control","no-cache"); //Forces caches to obtain a new copy of the page from the origin server

response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance

response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"

response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility

String userName = (String) session.getAttribute("User");

if (null == userName) {

 request.setAttribute("Error", "Session has ended. Please login.");

 RequestDispatcher rd = request.getRequestDispatcher("login.jsp");

 rd.forward(request, response);

}

//...

通过设置头信息和检查HttpSession中的用户名确保了浏览器不缓存页面,同时,如果用户未登陆,受保护的JSP页面将不会发送到浏览器,取而代之的将是登陆页面login.jsp。

运行logoutSampleJSP2

运行logoutSampleJSP2后将回看到如下结果:

1) 当用户退出后试图点击后退按钮,浏览器并不会显示受保护的页面,它只会现实登陆页login.jsp同时给出提示信息Session has ended. Please log in.

2) 然而,当按了后退按钮返回的页是处理用户提交数据的页面时,IE和Avant浏览器将弹出如下信息提示:

警告:页面已过期……(你肯定见过)

选择刷新后前一个JSP页面将重新显示在浏览器中。很显然,这不是我们所想看到的因为它违背了logout动作的目的。发生这一现象时,很可能是一个恶意用户在尝试获取其他用户的数据。然而,这个问题仅仅出现在后退按钮对应的是一个处理POST请求的页面。

记录最后登陆时间

上述问题之所以出现是因为浏览器将其缓存中的数据重新提交了。这本文的例子中,数据包含了用户名和密码。无论是否给出安全警告信息,浏览器此时起到了负面作用。

为了解决logoutSampleJSP2中出现的问题,logoutSampleJSP3的login.jsp在包含username和password的基础上还包含了一个称作lastLogon的隐藏表单域,此表单域动态的用一个long型值初始化。这个long型值是调用System.currentTimeMillis()获取到的自1970年1月1日以来的毫秒数。当login.jsp中的form提交时,loginAction.jsp首先将隐藏域中的值与用户数据库中的值进行比较。只有当lastLogon表单域中的值大于数据库中的值时Web应用才认为这是个有效的登陆。*博主点评:当然这里可以不用数据库(DB),建立一个application域的logon状态关管理类也是不错的办法,而且这个类可以实现更多的功能,比如限制[同一账号在不同地点同时登录]等.

为了验证登陆,数据库中lastLogon字段必须以表单中的lastLogon值进行更新。上例中,当浏览器重复提交数据时,表单中的lastLogon值不比数据库中的lastLogon值大,因此,loginAction转到login.jsp页面,并提示Session has ended.Please log in.清单5是loginAction中节选的代码段:

清单5

//...

RequestDispatcher rd = request.getRequestDispatcher("home.jsp"); //Forward to homepage by default

//...

if (rs.getString("password").equals(password)) {

 //If valid password

 long lastLogonDB = rs.getLong("lastLogon");

 if (lastLogonForm > lastLogonDB) {

session.setAttribute("User", userName); //Saves username string in the session object

stmt.executeUpdate("update USER set lastLogon= " + lastLogonForm + " where userName = '" + userName + "'");

 }

 else {

request.setAttribute("Error", "Session has ended. Please login.");

rd = request.getRequestDispatcher("login.jsp"); }

 }

 else { //Password does not match, i.e., invalid user password

request.setAttribute("Error", "Invalid password.");

rd = request.getRequestDispatcher("login.jsp");

 }

 //...

 rd.forward(request, response);

//...

为了实现上述方法,你必须记录每个用户的最后登陆时间。对于采用关系型数据库安全域来说,这点可以可以通过在某个表中加上lastLogin字段轻松实现。LDAP以及其他的安全域需要稍微动下脑筋,但很显然是可以实现的。

表示最后登陆时间的方法有很多。示例logoutSampleJSP3利用了自1970年1月1日以来的毫秒数。这个方法在许多人在不同浏览器中用一个用户账号登陆时也是可行的。

运行logoutSampleJSP3

运行示例logoutSampleJSP3将展示如何正确处理退出问题。一旦用户退出,点击浏览器上的后退按钮在任何情况下都不会是受保护的页面在浏览器上显示出来。这个示例展示了如何正确处理退出问题而不需要额外的培训。

为了使代码更简练有效,一些冗余的代码可以剔除掉。一种途径就是把清单4中的代码写到一个单独的JSP页中,通过标签<jsp:include>其他页面也可以引用。

Struts框架下的退出实现

与直接使用JSP或JSP/servlets相比,另一个可选的方案是使用Struts。为一个基于Struts的Web应用添加一个处理退出问题的框架可以优雅地不费气力的实现。这部分归功于Struts是采用MVC设计模式的因此将模型和视图清晰的分开。另外,Java是一个面向对象的语言,其支持继承,可以比JSP中的脚本更为容易地实现代码重用。在Struts中,清单4中的代码可以从JSP页面中移植到Action类的execute()方法中。

此外,我们还可以定义一个继承Struts Action类的基本类,其execute()方法中包含了清单4中的代码。通过使用类继承机制,其他类可以继承基本类中的通用逻辑来设置HTTP头信息以及检索HttpSession对象中的username字符串。这个基本类是一个抽象类并定义了一个抽象方法executeAction()。所有继承自基类的子类都应实现exectuteAction()方法而不是覆盖它。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。