JSP学习

1.项目格式:

IDEA中使用archetypeweb的构建就可以生成的,但是在Apple MAC上貌似不能用。IDEA中手动穿件标准的mvn项目,因为有web-app目录,IDEA会提示是否转成WEB项目选是。这里介绍一下WEB项目的目录结构

src/main/java: 放一些servlet之类的java文件

src/main/web-app/

         /jsp、/js、/img

         /WEB-INF/web.xml

这里的Web.xml是部署文件,指定一些servlet、listener之类的配置Servlet例子。访问http://domain/webroot/result.do的地址,get将访问servlet的GET方法。如果在Form 中 result.do的 POST时候将自动定位到POST方法。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>processServlet</servlet-name>
       <servlet-class>com.mvnbook.account.web.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>processServlet</servlet-name>
        <url-pattern>/result.do</url-pattern>
    </servlet-mapping>
</web-app>

 2. 相对路径。 

<form url='result.do'></form>

标签中url是submit之后的提交地址,相对于当前Html的路径。 如: 当前Html的路径是 web-app/html/test.html那么提交后的相对地址就是 http://domain/html/test.do 这种情况下去匹配Web.xm中的 servlet是匹配不上的, 因为上述url-pattern是相对于根的。 所以只能是 account-web/result.do这例 account-web是项目的根目录 

3. HttpServletRequest和HttpServletResponse对象

关于Request: request 对象的用于获取前端页面的参数 request.getParameter('size'). 也可以获取多个参数request.getParameters('size')如复选框。

request还可以用来转发, HttpRequestDispature dispature = request.getRequestDispature('/jsp文件的路径'); dispature.forward(requst,response);

关于response: Response 对象用来获取输出流的同时可以设置一些输出格式如 response.setContentType('img/jpeg'); 同时还可以往输出流中塞一些非Html的内容。同时还可以往Response中添加一些header字段、cookie值、甚至Redirect到的其他地址(这里 redirect是返回302让客户端做跳转)

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置输出格式
       resp.setContentType("image/jpeg");
      //获取输出流
        ServletOutputStream out = resp.getOutputStream();

// 读取资源文件
        ServletContext sc = getServletContext();
        InputStream is =  sc.getResourceAsStream("dowload.jpg");
// 向输出流中塞数据
        int read =0;
        byte[] result = new byte[1024];
        while ((read=is.read())!=-1){
            out.write(result,0,read);
        }
//输出
        out.flush();
        out.close();
    }

 4. ServletConfig, ServletContext

ServletConfig用户获取设置在某个serlvet中的init-parameters,方式

getServletConfig().getInitParameter('param');

getServletContext().getInitParameter('param');

其中Servlet param的设置方式, 例子分别设置init-param 和 context-param

   <servlet>
        <servlet-name>contextParamSevlet</servlet-name>
        <servlet-class>com.mvnbook.account.web.servlet.ContextParameterServlet</servlet-class>
        <init-param>
            <param-name>mail</param-name>
            <param-value>ygshen@ctrip.com</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>contextParamSevlet</servlet-name>
        <url-pattern>/servletconfig.do</url-pattern>
    </servlet-mapping>



    <context-param>
        <param-name>sessionid</param-name>
        <param-value>john</param-value>
    </context-param>

 5. ServletContextListener接口

接口的定义:实现接口的方法 ContextInitialized(ServletContextEvent event), contextDestroyed(). 

接口的作用: 通常servlet config parmater和servlet context parameter只能存字符串,如果想存储对象(如数据库链接对象时需要借助contextListener)

在initilaize阶段通过event获取servletContext对象并出示话对象,并存储在servletcontext中,其他的Servlet在自己的doget、dopost中可以直接拿蛋这些context中设置的对象,全剧唯一

 

Lister在Web。xml中的配置

<context-param>
        <param-name>sessionid</param-name>
        <param-value>john</param-value>
    </context-param>

    <listener>
        <listener-class>com.mvnbook.account.web.listeners.DogContextListener</listener-class>
    </listener>

 6. JSP 的原理: 

JSP文件会被Container编译成Servlet Class文件放在对应的目录下。文件的执行顺序时先

jspInit()-->service()-->destroy()

JSP中的

0. dirctive指令 <%page import='javax.servlet.ServletConfig'%>会被翻译成import语句

1.存在表达式语句: <% 表达式语句1;语句2.。。%> 那么这些代码将在Service方法中执行。

2。如果存在声明语句:会被拿到与service()方法评级的方法、语法块中执行。

<%! String abc=‘aaaa’;

public void test(){}

public void jspInit(){}

%>

3. 如果存在输出块  <% "test"%>将被翻译成 response.getPrintWriter().print("test")输出

 

7. JSP的隐式对象:

jsp最终是被翻译成servlet执行的,所以Servlet中获取隐式对象的方法 如getServletConfig(), getServletContext()同样适用于语法块中。那么如何设JSP的初时参数呢? 与Serlvet的不同点是<servlet-class>改成了jsp的文件路径。

<servlet>
    <servlet-name>jspinit</servlet-name>
    <jsp-file>/jsp/jspinit.jsp</jsp-file>
    <init-param>
        <param-name>mail</param-name>
        <param-value>ygshen@ctrip.com</param-value>
    </init-param>
</servlet>
    <servlet-mapping>
        <servlet-name>jspinit</servlet-name>
        <url-pattern>/test.do</url-pattern>
    </servlet-mapping>

 <%

   ServletConfig config=getServletConfig().getInitParam('mail');

%>

 

JSP对ServletContext、Request、Session、Page的支持和Servlet的支持对比

  Servlet隐式对象   JSP中的隐式对象
ServletContext getServletContext().setAttribute()

application.setAttribute()

application.getAttribute()

Session   request.getSession().setAttribute()  

session.setAttribute()

session.getAttribute()

request request request
page N/A  

pageContext.getServletContext().setAttribute()

(String)pageContext.getAttribute("page",PageContext.APPLICATION_SCOPE);

 

用来设置和获取Application级别的 变量 

 

 

pageContext.getSession().setAttribute()

(String)pageContext.getAttribute("page",PageContext.SESSION);

 

用来设置和获取Session级别的 变量  

 

pageContext.getReqeust().setAttribute()

 (String)pageContext.getAttribute("servlet",PageContext.REQUEST_SCOPE);

用来设置和获取REQUEST级别的 变量  

8. JSP中的Script/EL/Scriptless:

上面介绍了在JSP中写JAVA代码的方式 <% %> 但是对于UI工程师写JAVA明显是不现实的,所以一种叫做Scriptless的标签语言诞生了。

举例:Servlet中在Request中保存的对象 带到JSP中取

Servlet Method:

doPost(request,response){

  request.setAttribute("name","123");

  request.setAttribute("person",new Person("ygshen",34));

}

JSP Page:

如果使用JAVA Script的话:
<% String name=request.getAttribute("name")%> <%= name%>

<% Person person=(Person)request.getAttribute("person")%> <%= person.name%>

如果使用Scritpless的话

<jsp:useBean id="person" class="com.mvnbook.account.beans.Employee" scope="request"></jsp:useBean>
User First Name use bean: <jsp:getProperty name="person" property="firstName"></jsp:getProperty>

注:这里有几个名词

Script - 即在JSP中写的JAVA代码

ScriptLess: 即标签格式的HTML代码. 主要为了解决在JSP中书写JAVA的问题

EL- Expression Language 如${person.name} 

 9: <jsp:useBean></jsp:useBean> 标签的使用场景

a: 从Servlet跳转到JSP的时候。 Servlet中设置一些对象类型的Attribute 在JSP中可以使用usebean的方式获取设置的对象 以及输出对象的属性

<jsp:useBean id="idsetintheattribute" type="superclassorinterfaces" class="concreateclassname"></jsp:useBean>

输出  <jsp:getProperty name="idsettedintheattribute" property="propertyname">

b: 也可用于jsp到jsp 之间。比如在jsp1中通过form设值 在jsp2中可以用 usebean的方式接受对象

JSP1 文件负责对象属性的赋值:

// JSP1中通过Form的方式设置对象的属性。 
// 这里的input标签的name属性至关重要,它与 jsp2中的usebean属性的param名称相同遍可以直接传旨
<%--
  Created by IntelliJ IDEA.
  User: ygshen
  Date: 17/2/13
  Time: 下午11:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
<form action="jsp/person-get.jsp" method="post">
    User Name: <input type="text" name="name" />
    <br>
    Password: <input type="password" name="password" />

    <input type="submit" value="submit">
</form>
</body>
</html>

 JSP2负责对象的初始化 即值的接受

<%--
  Created by IntelliJ IDEA.
  User: ygshen
  Date: 17/2/13
  Time: 下午11:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
<jsp:useBean id="person" type="com.mvnbook.account.beans.Person" class="com.mvnbook.account.beans.Employee">
    <jsp:setProperty name="person" property="lastName" param="password"></jsp:setProperty>
    <jsp:setProperty name="person" property="firstName" param="name"></jsp:setProperty>
</jsp:useBean>


User Name: <jsp:getProperty name="person" property="firstName"></jsp:getProperty>
Password : <jsp:getProperty name="person" property="lastName"></jsp:getProperty>

</body>
</html>

 10: EL: JSP Expression Language

如果Servlet保存在attribute的对象属性是简单的数据类型 如果string 等用Usebean的方式看上去非常简单。但是如果对象属性又是对象 那么usebean在嵌套上酒力不从心了。 这里引进了 Expression Language。 格式 ${priopertyidintheservlet.property}

在servlet中设置复杂对象属性/

注意EL默认是不生效的 要默认打开

<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
package com.mvnbook.account.web.servlet;

import com.mvnbook.account.beans.Employee;
import com.mvnbook.account.model.dog;
import com.sun.net.httpserver.HttpServer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by ygshen on 17/2/13.
 */
public class ComplicateObjectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Employee employee = new Employee();
        dog doggie = new dog();
        doggie.setName("Balk");
        doggie.setColor("red");

        employee.setFirstName("ygshen");
        employee.setDoggie(doggie);
        req.setAttribute("user",employee);

        req.getRequestDispatcher("jsp/complicated-object.jsp").forward(req,resp);
    }
}

 在JSP中读取对象

<%--
  Created by IntelliJ IDEA.
  User: ygshen
  Date: 17/2/13
  Time: 下午11:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
 ${user.firstName} has a doogie named ${user.doggie.name} and its color is ${user.doggie.color}
</body>
</html>

 11.  EL Function = EL Taglib

定义EL Function 相当于调用一个类的静态方法,如帮助类等。 定义的过程

1. java class 定义一个static 方法

2. tag library xml 定义 *.tld

<?xml version="1.0" encoding="ISO-8859-1"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">

    <tlib-version>1.0</tlib-version>
    <short-name>myshortname</short-name>
    <uri>http://crip.com</uri>
这里name是方法的别名,可以在后续jsp中直接调用
function class 以及signature用于寻找用户自定义类的静态方法 <function> <name>rollDice</name> <function-class>com.ygshen.jsp.el.DiceRoller</function-class> <function-signature>int rollDice()</function-signature> </function> <!-- Invoke 'Generate' action to add tags or functions --> </taglib>

  

3. jsp中引用<%@ taglib prefix="jsp中用的前置应用标签(mine)" uri="http://ctrip.com" />。 那么这里就可以在jsp中使用该标签引用类中的静态方法了

${mine:rollDice()}

 

 

12。 JSTL:JSP Standard Tag Library

注意点:
需要引进第三方库

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>

解决的问题:替代在JSP中写JAVA代码的麻烦。 

核心库中的标签
<c:out value="${person.name}"></c:out>
<c:forEach items="${person.family.entrySet()}" item=${family}></c:forEach>

实例:在Servlet中设置request scope的attribute 在JSP中使用Java Script和JSTL的方式展示属性

public class HomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HashMap<String,String> family = new HashMap<String, String>();
        family.put("father","John");
        family.put("mother","Kelly");
        family.put("brother","Done");
        Dog mydog = new Dog("旺财",1);
        Person p = new Person("ygshen",10, mydog,family);

        req.setAttribute("person",p);

        req.getRequestDispatcher("index.jsp").forward(req, resp);
    }
}
<%@ page import="java.util.HashMap" %>
<%@ page import="com.ygshen.jsp.modal.Person" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Iterator" %>
<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="mine" uri="http://crip.com" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title></title>
</head>
<body>
<%
    Person p  = (Person)request.getAttribute("person");
    HashMap<String,String> family = p.getFamily();
    Iterator iterator = family.entrySet().iterator();
%>
<!--Use Script -->
<table>
    <thead>
        ${person.name}
    </thead>
    <tbody>
    <tr>
        <td>
            Name
        </td>
        <td>
            ${person.name}
        </td>
    </tr>
    <tr>
        <td>
            family members:
        </td>
        <td>
            <%
                while (iterator.hasNext()){
                    Map.Entry entry = (Map.Entry)iterator.next();
            %>
            <!---这里用EL 输出上下文中的变量-->
                <%=entry.getValue()%>
            <%
                }
            %>
        </td>
    </tr>
    </tbody>
</table>

<!---Use jstl-->
<table>
    <thead>
    ${person.name}
    </thead>
    <tbody>
    <tr>
        <td>
            Name
        </td>
        <td>
            ${person.name}
        </td>
    </tr>
    <tr>
        <td>
            family members:
        </td>
        <td>
           <c:forEach items="${person.family.entrySet()}" var="family">
               ${family.getValue()}
           </c:forEach>
        </td>
    </tr>
    </tbody>
</table>
</body>
</html>

  

 

posted on 2016-11-26 22:43  ygshen  阅读(368)  评论(0编辑  收藏  举报

导航