jsp基础知识2

12年前
一、路径问题
 
//地址的问题
路径问题
 链接
 提交
 重定向
  转发
 相对路径
  相对于当前目录开始
  链接提交重定向转发:写相对路径,四个都一样
 绝对路径
  /    从根目录开始

 /jsp02/  链接、提交、重定向
 /绝对路径,这个是jsp02后面那个/,其中jsp02为应用名
 
页面转发
<%
request.getRequestDispatcher("a/1.jsp").forward(request,response);
%>
假设通过转发的话,相对路径可能会存在问题
所以在mvc模式下最好是采用绝对路径

二、为什么不能将css,img目录放到web-inf下面去呢?
 浏览器首先获取到html页面,当发现需要css,或者图片的时候,会再次向服务器请求。
 因为浏览器不能直接访问css,img文件

查看webroot/web-inf/jsp/login_form.jsp
 <%@page pageEncoding="utf-8"%>
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title></title>
  <link rel="stylesheet" type="text/css"
   href="css/style.css" />
 //这个地方的位置为什么是这样的呢?
 //是相对于根目录下的
 //主要是看web.xml怎么配置的
</head>
 
<h1>1.jsp</h1>
<%
System.out.println(request.getContextPath());
 %>
<a href="../b/2.jsp">two</a>
<a href="/whatisjava.jsp.02/b/2.jsp">two</a>
<a href="%=request.getContextPath()%">two</a>
转发,地址栏中地址不变
重定向,地址栏中地址改变
 转发:
       一件事多个组件协同做用转发,比如一个接收数据,另外一个处理数据;一个请求
   转发只能在本应用内部使用
 重定向:
   一件事的结束是另外一件事的开始;两个请求
   重定向可以跨应用
 request.getRequestDispatcher()是请求转发,前后页面共享一个request
 response.sendRedirect()是重新定向  前后页面不是一个request
 sendRedirect是通知IE再次提交一个http请求,
 dispatcher是直接转到目的地址,最直接的表现
 应该是dispatcher后的IE地址栏地址是不变的
 request.getRequestDispatcher()是服务器端跳转
 response.sendRedirect()是客户端跳转
 转发只能转到本应用内部转发-----相对于转发的绝对地址
 重定向可以跨应用转发----
注册用户
 配置文件
 <action path="/addUser"
  type="org.whatisjava.action.AddUserAction">
  <forward name="success" path="/loginForm.action" redirect="true" />
  <forward name="fail" path="/WEB-INF/jsp/register_form.jsp" />
 </action>
package org.whatisjava.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.beanutils.BeanUtils;
import org.whatisjava.controller.Action;
import org.whatisjava.dao.UserDao;
import org.whatisjava.domain.User;
public class AddUserAction extends Action {
 @Override
 public String execute(HttpServletRequest request,
   HttpServletResponse response) {
  try {
   String number1 = request.getParameter("number");
   //获得session验证码
   HttpSession session = request.getSession();
   String number2 = (String) session.getAttribute("number");
   //获得cookies里面的验证码
   
   //比较number1,number2,如果number2
   if (number2 != null && number2.equals(number1)) {
    UserDao dao = new UserDao();
    User user = new User();
    //用户
    Map map = request.getParameterMap();
    BeanUtils.populate(user, map);
    //写入数据到数据库
    dao.addUser(user);
    return "success";
    
    //注册完了,肯定用重定向
   } else {
   ********************************************************
    request.setAttribute("error_msg", "验证码错误");
   *********************************************************
    return "fail";
   }
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
 }
}
验证码不对,提示错误
        <tr>
        <td valign="middle" align="right">
         验证码:
         <img id="num" src="image" />
         <a href="javascript:;" onclick="document.getElementById('num').src = 'image?'+(new Date()).getTime()">换一张</a>
    
        </td>
        <td valign="middle" align="left">
         <input type="text" class="inputgri" name="number" />
         *****************************************************
         <%
         String msg=(String)request.getAttribute("error_msg");
         %>
         <span><%=(msg==null)?"":msg %></span>
         ******************************************************
        </td>
       </tr>
 
        <td valign="middle" align="left">
         <input type="text" class="inputgri" name="number" />
         <span>${error_msg}</span>
        </td>
 
 
用oracle创建的user表,产生的hibernate的mapping映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="org.whatisjava.domain.user" table="WHATISJAVA_USER" schema="SONGXL">
        <id name="id" type="long">
            <column name="U_ID" precision="12" scale="0" />
            <generator class="sequence" >
            <param name="sequence">WHATISJAVA_USER_SEQ</param>
            </generator>
        </id>
        <property name="username" type="string">
            <column name="U_USERNAME" length="50" />
        </property>
        <property name="password" type="string">
            <column name="U_PASSWORD" length="50" />
        </property>
        <property name="name" type="string">
            <column name="U_NAME" length="50" />
        </property>
        <property name="age" type="short">
            <column name="U_AGE" precision="3" scale="0" />
        </property>
        <property name="sex" type="string">
            <column name="U_SEX" length="1" />
        </property>
    </class>
</hibernate-mapping>
 

MVC所有的请求都交给中央控制器
 smartstruts-config.xml来指挥中央控制器
用来MVC之后,JSP基本上都是页面了。
 
四、JSP 2.0中的EL表达式(功能很强大,可以帮助程序员减少在JSP中的代码量)
action中针对验证码错误的提示:
response.setAttribute("error_msg","验证码错误");

显示页面:
<%
Sting msg=request.getParametera("error_msg");
%>
<span><%=(msg==null)''?"msg"%></span>
 
通过jsp 2.0,EL可以将显示页面中的对应语句用下面语句代替
${error_msg}
//JSP引擎既能把<%%>转换也能把${}转换
//最终也会转换成一大段jsp代码
 
EL表达式,功能非常强大。能很大程度降低代码量
${requestScope.msg}
对应代码:
<%
Object obj=request.getAttribute("msg");
if (obj!=null){
 out.write(obj.toString());
}else{
 out.write("");
}
%>

${requestScope.user} //通过request获得user对象的toString方法
${requestScope.user.name}  //通过request获得user对象的toString方法并调用getName方法
${可以写表达式;+-*/}
EL
 ${pageScope.msg}
 ${requestScope.user}
 ${sessionScope.msg}
 ${applicationScope.msg}
 相同的功能,都能存数据和取数据
 ${msg}
  这样是什么意思呢?从范围小到大,依次搜索,取小值。
 ${requestScope.user.msg}
         ===
        属性方法
四个范围
 pageContext
 request
 session
 application
这4个都有setAttribute,getAttribute
可以从tomcat下面随便找个jsp程序看下即可
 ServletContext application=null;  //说明application实际上就是ServletContext
 
 application.getAttribute
 application.setAttribute

一个包里面可能要定义多个servlet,但是servlet定义的application
所以一个应用就一个这样的application,比如在线的统计数字
属于共享的空间
session:一个会话一个session
request:一个用户可能有多个请求
pageContext:共享范围一个页面,一个页面分配一个这样对象;临时存放数据的空间
 pageContext.setAttribute
       .getAttribute
 
java我们要训练,结合场景来学习的。
    当时我是在什么场景学的这些东西
jsp里面没有jsp代码就不叫jsp了。
 EL表达式的功能是有限的,不能替代if语句和for循环。
 那么用什么能替代呢?
标记库----某些人开发的一些jar包
 先学会用标记库,再做出一个标记库
 标记库和EL表达式是jsp的灵魂
EL
${mesg}
标记库---好多企业里面都会开发自己的标记库
<some name="">
</some>
我们要讲的标记库JSTL==java standard tag library
我们首先学怎么用
 先搞到java包
1可以从oracle网站上下载
2、tomcat自带,tomcat6\webapps\examples\WEB-INF\lib
 jstl.jar
 standard.jar
首先建立一个jstl目录,下面建立1.jsp
 <%@taglib uri="" prefix=""%>
      ===
      
 这句话的意思,告诉jsp引擎,我下面将使用taglib。
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
      =====================            ===前缀
         怎么填写的呢?来源于哪里?比如standard.jar
       META-INF下有好多tld文件。随便打开一个
       查看里面的urihttp://java.sun.com/jsp/jstl/core
由于可能存在多个公司的标记库,所以前缀的标记也是可以变化来却分不同公司的标记库的 
相当于声明
 
 
 
<c:forEach>
</c:forEach>
<f:forEach>
</f:forEach>
 用了标记库之后,可以写出类似html的东西,但还属于java代码
<c:if  test="${requestScope.num>100}"〉
    ==================
             这里必须是一个EL表达式,如果是true,则输出下面这行,false不显示
 ${requestScope.num}
</c:if>
 
<c:choose>
 <c:when test="${requestScope.num gt 200}">
  <h1>
   200
  </h1>
 </c:when>
 <c:when test="${requestScope.num gt 100}">
  <h1>
   100
  </h1>
 </c:when>
 <c:otherwise>
  <h1>
   ERROR
  </h1>
 </c:otherwise>
</c:choose>
<c:when></c:when>可以有多个
<c:otherwise></c:otherwise>只有一个

<c:forEach items="${requestScope.arry1}" var="str">
       ============= ===
       必须是EL表达式,这个  
       表达式取出来得值必须是
       一个集合对象;这里是循
       环的次数;集合里面有几个
       对象就循环几次;把元素从集合
       里面取出来以var值为名称放到
       pageContext里面,后一次覆盖前一次
<h1>
  ${str}
</h1>
</c:forEach>

以上代码的意思是反复输出forEach里面的内容。
 
<table border="1" width="80%">
 <tr>
  <td>
   Name
  </td>
  <td>
   Age
  </td>
 </tr>
 <c:forEach items="${requestScope.user_list}" var="u">
  <tr>
   <td>
    ${u.name}
   </td>
   <td>
    ${u.age}
   </td>
  </tr>
 </c:forEach>
</table>
 
 

JSTL+hibernate+smartstruts
 
如何生成一个不会重复的字符串
  只要这些人一注册服务器端就要创建一个唯一的文件夹
  上传的文件名最好能修改下,要不会形成注射
 
package org.whatisjava.test;
import java.util.UUID;
public class TestUUDI
{
 public static void main(String [] args){
 UUID uuid=UUID.randomUUID();
 System.out.println(uuid.toString());
 }
}
如何建造目录
 file.mkdir

boolean mkdir() 
  创建此抽象路径名指定的目录。 
boolean mkdirs() 
  创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。 
FileOutputStream fos=new FileOutputStream("file.jpg");
 针对文件的输出流是覆盖,所以要注意一定要先删除再写新的