Servlet+Jsp服务

上一篇我们介绍了一些常见的web服务器,和JavaEE项目的创建,但我们在写大型项目的时候一般建的都是Maven项目,它可以帮我们很好的管理jar包,一个大型项目,我们可能会用到上百个jar包,而我们自己管理这些jar包,是很费力的,于是maven项目可以帮我们管理它,我们在使用时只需要提前加入jar包的依赖就好;

maven

管理jar包时,会连接网络下载jar包

默认仓库的位置 C:\Users\Administrator.m2

maven 的要素:

groupId 组织编号 com.westos
artifactId 项目名称 web2
version 版本 1.0

目录结构

src
    |-main
        |-java      (java代码)
        |-resources (配置文件)
    |-test
        |-java
        |-resources
pom.xml (可以添加 jar依赖,设置jdk版本,项目的字符编码)

Maven的核心功能便是合理叙述项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包,而这里pom.xml文件对于学了一点maven的人来说,就有些熟悉了,怎么通过pom.xml的配置就可以获取到jar包呢?pom.xml配置文件从何而来?等等类似问题我们需要搞清楚,如果需要使用pom.xml来获取jar包,那么首先该项目就必须为maven项目,maven项目可以这样去想,就是在java项目和web项目的上面包裹了一层maven,本质上java项目还是java项目,web项目还是web项目,但是包裹了maven之后,就可以使用maven提供的一些功能了(通过pom.xml添加jar包)。

<packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Servlet+Jsp服务_第1张图片

maven仓库

通过pom.xml中的配置,就能够获取到想要的jar包(还没讲解如何配置先需要了解一下仓库的概念),但是这些jar是在哪里呢?就是我们从哪里获取到的这些jar包?答案就是仓库。

仓库分为:本地仓库、第三方仓库(私服)、中央仓库

  1. 本地仓库:

    Maven会将工程中依赖的构件(Jar包)从远程下载到本机一个目录下管理,每个电脑默认的仓库是在 $user.home/.m2/repository下

一般我们会修改本地仓库位置,自己创建一个文件夹,在从网上下载一个拥有相对完整的所有jar包的结合,都丢到本地仓库中,然后每次写项目,直接从本地仓库里拿就行了

修改本地库位置:在$MAVEN_HOME/conf/setting.xml文件中修改,
在这里插入图片描述
                
 D:\java\maven\repository:就是我们自己创建的本地仓库,将网上下载的所有jar包,都丢到该目录下,我们就可以直接通过maven的pom.xml文件直接拿。

  1. 第三方仓库

    第三方仓库,又称为内部中心仓库,也称为私服;
    这种仓库一般指公司内部享有的私服仓库,我们先不做过多介绍;

  2. 中央仓库
     Maven内置了远程公用仓库:http://repo1.maven.org/maven2

这个公共仓库是由Maven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。目前是以java为主

工程依赖的jar包如果本地仓库没有,默认从中央仓库下载

  • 阿里云的 maven仓库网址: http://maven.aliyun.com/nexus/content/groups/public/

学会了上面的内容我们就可以建一个idea环境下的maven仓库了;
Servlet+Jsp服务_第2张图片
Servlet+Jsp服务_第3张图片
然后输入我们的组织名称,项目名称;
Servlet+Jsp服务_第4张图片

建好以后我们先配置pom.xml文件,将各种jar包的依赖加进去,然后创建一个文件夹叫webapp这样就成为了一个完整的maven项目的目录结构,在webapp项目里我们还需要创建一个WEB-INF文件夹,让他成为一个合格的放置页面的文件;然后我们按照上一篇博客中所讲的将tomcat服务器也加进去,这样就完整了;


Servlet

  • 简介:
    Servlet是sun公司提供的一门用于开发动态web资源的技术。
      Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
      1、编写一个Java类,实现servlet接口。
      2、把开发好的Java类部署到web服务器中。

  • 流程:
    Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
      ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
      ②装载并创建该Servlet的一个实例对象。
      ③调用Servlet实例对象的init()方法。
      ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
      ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
      Servlet+Jsp服务_第5张图片

这里我们要先补充一点知识;
表单提交的两种方式

  1. get 请求,会把请求参数跟在地址之后,格式是
?参数名1=参数值1 & 参数名2=参数值2 ...

传递参数的长度有限

  1. post 请求, 请求参数会包含在请求体内,对外不可见
参数名1=参数值1 & 参数名2=参数值2 ...

没有长度限制, 注意 post 并不是真正安全(并没有对参数做加密处理);

1. post 请求中的汉字会有乱码问题(重点)

原因:

String sex = URLEncoder.encode("男", "utf-8");
System.out.println(sex);
// iso-8859-1
String result = URLDecoder.decode("%E7%94%B7", "iso-8859-1");
System.out.println(result); // ç”·

解决方法,在调用 getParameter 方法之前:

request.setCharacterEncoding("utf-8")

2. request 重要方法(重点)

request.getParameter(“参数名”) ==> 返回参数值
request.getParameterValues(“参数名”) ==> 返回参数值的数组
request.setCharacterEncoding(“解码的字符集”);

request.getMethod(); ==> 返回请求方式 get, post
request.getRequestURI(); ==> 返回当前的请求路径
request.getRemoteAddr(); ==> 获取访问者的ip地址

3. 一个请求分别几个部分(了解)

GET 两个部分
GET 路径/HTTP 1.1   ==> 请求行
请求头
    Host: 要访问那个虚拟主机 一个服务器下有多有 host, 每一个host 下,又有多个应用程序
    Accept: 可以处理的内容格式:例如 text/html
    Accept-Encoding : 能够支持的压缩格式
    Accept-Language : 支持的语言, 例如 zh-CN
POST 三个部分
    Content-Type: 请求体的格式 application/www-form-urlencoded (普通表单格式)
    Content-Length: 请求体内容的长度
请求体
    post的请求参数放入了请求体当中,例如:username=zhangsan&password=123
    如果有中文,会自动编码 

4. 响应分成3个部分(了解)

  1. 状态码

    • 200 表示响应正确返回
    • 404 表示请求的资源不存在
    • 500 表示服务器内部出现了异常
    • 304 表示该内容没有被修改,那么服务器只会返回状态码和头,不需要返回响应体(图片,html,css,js)
    • 400 请求参数格式有误.
    • 403 验证没通过,或权限不足
  2. 响应头

    • content-type: 响应的内容格式, 例如 text/html;charset=utf8
    • content-length: 响应体的长度(字节)
    • Date: 响应生成时间
  3. 响应体
    html内容,图片内容

6. 请求转发(重点)

servlet 中还是用来处理表单请求

跳转至jsp (请求转发)

jsp 用来生成html代码并返回

request.getRequestDispatcher("jsp路径").forward(request, response);

如何把servlet中的变量传递给jsp显示

作用域传参

request.setAttribute("变量名", 对象);

取(在jsp页面),通过 EL 表达式取

${ 变量名 }
${ 变量名.属性名 }    el 表达式中的属性名,对应着java对象中的 get,set方法名

servlet 服务器端小程序

@WebServlet(urlPatterns="/映射路径")
class MyServlet extends HttpServlet {

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException{
        // 处理请求和响应的代码
        String 参数值 = request.getParameter("请求参数名");
        // 用response返回响应
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("");
    }
}

jsp 也可以动态html

<%@page contentType="text/html;charset=utf-8" language="java"%>
<html>
    <%
        java
    %>
html>

Servlet 的生命周期

  • 当 servlet 首次被访问时 ,调用构造方法,只调用一次(只有一个servlet对象被创建)
  • 紧接着调用初始化 init 方法,也是只调用一次
  • 根据请求方式,调用 service,或 doGet 或 doPost (请求几次,就会被调用几次)
  • 当应用程序停止前,调用 destroy 方法,只调用一次
    Servlet+Jsp服务_第6张图片
    这些方法都是由 tomcat 容器来调用, 这种方式称之为控制反转

Servlet 默认是在第一次访问时被加载,也可以配置服务器启动时被加载 loadOnStartup = 数字
数字代表优先级,数字小的表示优先级高

还可以设置初始化参数(了解)

Servlet 2.5 以前的版本

webapp/WEB-INF/web.xml (部署描述符)
在这里也可以配置servlet中的所有功能,例如:

<servlet>
    
    <servlet-name>oldservlet-name>
    
    <servlet-class>web.OldServletservlet-class>
    
    <init-param>
        <param-name>nameparam-name>
        <param-value>李四param-value>
    init-param>
    
    <load-on-startup>3load-on-startup>
servlet>

<servlet-mapping>
    
    <servlet-name>oldservlet-name>
    
    <url-pattern>/oldurl-pattern>
servlet-mapping>

jsp 中的 EL 表达式

expression language
主要作用是从作用域中取出变量并显示

request.setAttribute(“变量名”, 值);

页面上可以使用 ${ 变量名.属性 }

1. 做简单运算

算数运算 ${ 18 + 20 }

比较运算 ${ 18 > 20 }

逻辑运算 ${ 18 > 20 and 19 < 30 }

逻辑运算 ${ 18 > 20 or 19 < 30 }

逻辑运算 ${ not (18 > 20) }

三元运算 ${ (false)?"真":"假" }

空运算 ${ empty names}

2. 用来显示作用域中的变量 (重点)

  • list 显示 可以用 [下标]
  • 要显示大小 list.size()
  • map 显示 可以用 ${map.key}
  • map 显示 可以用 ${map[“key”]}
  • map 显示 可以用 ${map.get(“key”)}
  • 建议map使用字符串作为key,如果非要用整数作为key,必须用 Long, 只能用[]语法取,不能用.语法
  • 显示java bean, 底层实际调用的是get方法,嵌套的对象可以多次调用.语法

3. 11 个隐式对象

  • param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值
  • paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组

4. 标准标签库

简称jstl

  1. 引入标签库 jar包
<dependency>
    <groupId>jstlgroupId>
    <artifactId>jstlartifactId>
    <version>1.2version>
dependency>
  1. 在页面上声明要使用的标签库
<%@ taglib prefix="标签前缀" uri="标签的唯一标识" %>

核心标签

  • forEach 进行遍历


其中 varStatus 中有两个属性 count(从1开始) , index(从0开始)

  • if 条件判断
内容
  • choose 条件判断

    内容
    内容
    内容
    内容

jsp 底层原理

在第一次发送请求时,会把 jsp 文件转义为 java(servlet) 代码,并进一步编译为 class 文件

把页面上的静态内容(html代码),使用 out.write 方法进行打印,其中 out 对应着响应的字符输出流
至于 <% 代码 %> 中的代码会原封不动搬移到 jsp 转义生成的 java 代码中

本质仍是一个 servlet

新的方式

jstl 标签 + EL 表达式 (推荐)

旧的生成动态内容的方式

  1. <% 代码 %> 称为jsp脚本, 其中的变量是方法内的局部变量
  2. <%= 表达式%> 称为jsp表达式, 用来输出值,不用加;结束
    使用jsp表达式获取作用域内容 <%= request.getAttribute("name") %>
    使用el表达式获取作用域的内容 ${name}
  3. <%! 代码 %> jsp的声明, 其中的变量是类的成员变量
  4. 注释 <%-- 注释内容 --%> 会阻止java代码的运行,包括 jstl 标签和 EL 表达式 都可以使用这种办法注释
  5. <%@ 指令名 %>
    • page 用来指明页面的内容类型和编码方式 , isELIgnored=“true|false” 表示是否忽略 EL 表达式
    • taglib 用来引入一个标签库 prefix=“前缀” uri=“标签库的标识”
    • include 用来执行页面的包含操作
<%@ include file="文件路径" %>

重点掌握 4, 5

记住用户名密码这些参数的操作,称之为维护状态(记住这些信息)

cookie (了解)

cookie 本意是小甜点, 在web开发中是用来维系状态的一种技术

服务器要向浏览器返回cookie

// 创建cookie
Cookie c = new Cookie(,);
response.addCookie(c);

浏览器再发送请求时,会把这些cookie值重新发送给服务器

Cookie[] cookies = request.getCookies();
// 遍历 cookies 数组

应用场景: 自动登录、 记录访问网页

cookie 的属性

maxAge 用来设置 cookie 的寿命,

  • 默认不设置(-1)表示浏览器关闭寿命就到期
  • 指定一个正整数(单位秒),指定cookie存活多久
  • 设置为 0,表示由服务器端删除该cookie

httpOnly 用来设置是否禁止 js 代码访问 cookie

有安全风险,因为信息是存储在浏览器端的

session (重点)

把这些状态信息存储在服务器端,安全性要比 cookie 高很多

1. 存储信息

// 拿到 session 对象
HttpSession session = request.getSession();
// 存储信息
session.setAttribute("名",);

2. 获取信息

// 拿到 session 对象
HttpSession session = request.getSession();
// 获取信息 
session.getAttribute("名"); // 返回上一次存储的值

3. 删除信息

session.removeAttribute("名"); // 返回被移除的值

session.invalidate(); // 让session失效(全部清空)

默认生命周期,
第一次调用 request.getSession() 创建 session对象
如果隔了 30 分钟没有向服务器发送请求,session 会自动失效

如果要改变失效时间,可以在 web.xml中:

<session-config>
    <session-timeout>30session-timeout>
session-config>

跟浏览器的关系:一个浏览器对应服务器端的一个 session 对象
他们存储的信息互不干扰

对比 cookie 和 session

  • 安全性上, session的安全性高,cookie的信息存在浏览器端所以不安全
  • 存储的类型, session 存储的类型是 Object, cookie 只能存字符串(并且需要进行编码处理)
  • 存储大小, session 理论上没有限制(但不建议存储太多内容), cookie 的限制:每个cookie不能超过4k,每个网站cookie个数也有限制的
  • 失效时间, session 两次请求间隔30分钟, cookie 默认关闭浏览器失效,还可以通过 maxAge 调整的更长

请求重定向 (重点)

请求转发

request.getRequestDispatcher("跳转路径").forward(request, response);

请求重定向

response.sendRedirect("跳转路径");

二者的区别

  • 请求转发的地址不会改动,始终是刚开始的地址, 请求重定向在跳转后,地址栏会变为目标地址
  • 请求转发是一次请求,跳转操作在服务器内部发生;请求重定向是两次请求,跳转操作是在浏览器,服务器之间发生
  • 请求转发可以使用 request.setAttribute 进行值的传递;请求重定向需要使用 session.setAttribute 进行值的传递

request, session 作用域(scope)对象 (重点)

作用范围限于一次请求
request.setAttribute(key, value);
request.getAttribute(key) ${key}
request.removeAttribute(key);

作用范围同一个浏览器的多次请求之间(一次会话)
session.setAttribute(key, value);
session.getAttribute(key) ${key}
session.removeAttribute(key);

页面作用域,作用范围限于当前页面
page

应用程序作用域,作用于整个应用程序
application

page < request < sesssion < application

${ key } 会从小的作用域向大的作用域依次查找,直到找到为止

也可以利用前缀精确地找某个作用域:

  • pageScope page 作用域
  • requestScope 请求作用域
  • sessionScope 会话作用域
  • applicationScope 应用程序作用域

jsp 中的隐式对象 (了解)

9 个

  • pageContext 页面作用域
  • request 请求对象
  • session 会话对象
  • application 应用程序对象
  • response 响应对象
  • out 响应输出流
  • page 当前的jsp对象(this)
  • config 用来读取和jsp配置相关的信息
  • exception 必须在当前页面的 page 指令中添加 isErrorPage=“true”, 表示一个异常对象

你可能感兴趣的:(java+web)