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()
用来设置和获取Application级别的 变量
pageContext.getSession().setAttribute()
用来设置和获取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>