《JavaEE初阶》Servlet

《JavaEE初阶》Servlet

编写一个Servlet的helloworld

1. 认识Maven并创建maven项目:

Maven是一个"构造工具",它能针对代码进行依赖管理,编译,打包,验证,部署等功能.

在我们之前学习的代码较为简单,并不需要进行打包.

而在一个复杂的项目中,依赖许多的第三方库,并且可能有多个模块,模块与模块之间存在依赖关系,这个时候就可以将Maven作为一个针对复杂项目进行管理的解决方案.

在Java中,也有其他构建工具,但Maven是当下最主流的构建工具.当然其他语言也有自己的构建工具.

我们使用Maven主要是以下两个功能

  • 管理依赖: 使用maven将第三方库下载并导入项目.

  • 打包: 将代码编译好并且将.class文件压缩为.jar或者.war文件

典型的Maven项目文件结构:

在这里插入图片描述

src:

  • main : 放业务代码

    • java : 存放java代码

    • resources: 存放代码依赖的资源:图片,HTML,CSS等等.

  • test: 放测试代码

  • prm.xml: maven 项目中 最核心的文件,描述这个项目的属性信息.

使用IDEA创建一个maven文件

2. 引入依赖:

我们在maven项目中写servlet程序,这需要引入依赖(servlet的jar包).

在网站中下载servlet 3.1

Maven Repository: javax.servlet » javax.servlet-api » 3.1.0 (mvnrepository.com)

在这里插入图片描述

使用 dependency 标签将代码复制进pom.xml中,等待IDEA自动下载.

3.创建目录:

这里的创建目录必须严格按照以下格式,因为这是tomcat的硬性要求,为了让我们的程序被tomcat识别,不可自己修改.

在main目录下创建以下文件

在这里插入图片描述

并且在web.xml中复制粘贴:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

4. 编写代码:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/hello")
public class Helloservlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello world");
        resp.getWriter().write("hello world");
    }
}

代码解析:

  • HttpServlet来自于我们之前引入的Servlet jar包的.如果我们之前maven引入Servlet失败,这里就会报错.

  • 对于这个代码,是不需要我们写main方法的,main方法在tomcat 中, 由tomcat 在适当的时机调用.

  • HttpServletRequest req, HttpServletResponse resp分别对应HTTP请求和HTTP响应.

    HttpServletRequest req 在执行doget会解析 HTTP 请求并写入req.

    HttpServletResponse resp 在执行doget会先是一个空对象, 当服务器返回响应后再写入resp.

  • System.out.println(“hello world”); 并不会打印到浏览器页面上,会作为tomcat的运行日志并打印在控制台

  • resp.getWriter().write(“hello world”); 打印在浏览器页面.

  • @WebServlet(“/hello”) 这个注解约定了HTTP请求上的URL是什么path.

5. 打包

这个较为简单,我们直接点击maven,按下package,就会将package以及上述操作执行完毕.
在这里插入图片描述

但是这里得到的是jar包,而Tomcat能识别的却是war包,所以我们需要在maven的pom.xml增加以下信息

    <packaging>war</packaging>

    <build>
        <finalName>hello_servlet</finalName>
    </build>

第一句可以控制我们打包后生成的压缩包是一个war包

第二句可以控制我们打包后生成的压缩包名字.

6. 部署

将我们生成的war包复制粘贴到我们的webapps目录下

7.验证

尝试去利用回环ip的path访问这个网页.

优化打包部署操作.

我们已经在写出上面的代码过程中,我们可以发现1 2 3 是每次项目创建时都必不可少的,我们无法进行更加简单的优化让这个更加便捷,4 是我们自己编写的代码,也不能优化,对于7 是我们的自行测试,

而如果不进行优化打包部署操作,我们每一次修改代码,就需要再一次打包,复制粘贴去tomcat并重启tomcat,这个 操作是非常不方便我们进行开发的.

所以我们需要利用一个IDEA插件来帮助我们完成这个操作.

在这里插入图片描述
在这里插入图片描述

常见的错误:

  • 404 : 大概率是URL写错了.或者web.xml写错了

  • 405: method not allow, 如果这个请求是post请求,但是只实现了doget方法.

  • 500 : 服务器挂了,一般就是代码报错导致启动失败.

  • 返回空白页面: 应该是忘记写write了

  • 无法访问此网站: tomacat没有正确启动.

ServletAPI:

我们在之前已经学习了使用from和ajax构造HTTP请求,

利用ajax构造请求.

在这个目录下创建tset.html写我们的ajax请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>

     <script src="jquery.min.js"></script>
<script>
    $.ajax({
        type:'GET',
        url: 'hello',
        success: function(body){

             console.log(body);
          }
        })

 </script>
</body>
</html>

使用第三方工具postman构造请求

我们虽然可以使用ajax来构造我们的HTTP请求,但每一次构造请求都显得过于复杂,需要我们每一次都手写ajax代码来构造.

而使用postman则不需要这么复杂了.

下载postman

https://www.postman.com

使用postman构造HTTP请求:
在这里插入图片描述
在这里插入图片描述

HttpServlet:

  1. init

    在 HttpServlet 实例化之后被调用一次

  2. destory

    在 HttpServlet 实例不再使用的时候调用一次

  3. service

    收到 HTTP 请求的时候调用

  4. doGet

    收到 GET 请求的时候调用(由 service 方法调用)

  5. doPost

    收到 POST 请求的时候调用(由 service 方法调用)

  6. doPut/doDelete/doOptions/…

    收到其他请求的时候调用(由 service 方法调用)

我们一般只重写doxxx方法,对于不同方法的HTTP请求会调用对应的doxxx方法.

HttpServlet的生命周期:

HttpServlet实例化之后先调用一次init,在收到HTTP请求之后会调用service,在service内部调用对应请求的doxxx方法,当HttpServlet实例不再使用再调用destroy.

在这里插入图片描述

HttpServletRequest

表示一个HTTP请求,我们可以通过它的方法来获得HTTP请求的各种信息(方法,URL,版本号,header,body)

方法简介
String getProtocol()获取请求协议的版本和名称
String getMethod()获取请求协议的方法
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
String getContextPath()返回指示请求上下文的请求 URI 部分。
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
Enumeration
getParameterNames()返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
String getParameter(String
name)以字符串形式返回请求参数的值,或者如果参数不存在则返回null。
String[]
getParameterValues(String
name)返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null.
Enumeration
getHeaderNames()返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)以字符串形式返回指定的请求头的值。
String getCharacterEncoding()返回请求主体中使用的字符编码的名称。
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null。
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。
InputStream getInputStream()用于读取请求的 body 内容. 返回一个InputStream 对象.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/testreq")
public class testreq extends Helloservlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置返回响应的字符集,使得br能被正确解析.
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(req.getMethod());
        resp.getWriter().write("<br>");
        resp.getWriter().write(req.getProtocol());
        resp.getWriter().write("<br>");
        resp.getWriter().write(req.getContextPath());
        resp.getWriter().write("<br>");
        resp.getWriter().write(req.getRequestURI());
        resp.getWriter().write("<br>");
        resp.getWriter().write(req.getQueryString());
        resp.getWriter().write("<br>");
        Enumeration<String> enumeration = req.getHeaderNames();
        while(enumeration.hasMoreElements()){
            String headernanme = enumeration.nextElement();
            resp.getWriter().write(req.getParameter(headernanme));
            resp.getWriter().write("<br>");
        }
        resp.getWriter().write("这里结束");



    }
}

如果我们发送的是post请求,这需要使用dopost方法:

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("Studentid = " +  req.getParameter("Studentid"));
        resp.getWriter().write("<br>");
        resp.getWriter().write("Classid = " +  req.getParameter("Classid"));
    }

我们在之前的学习就已经知道post是利用body来传送数据, 在body中的数据一般以这两种数据来组织格式:

  • application/x-www-from-urlencode

  • application/json

而application/x-www-from-urlencode 就是一些简单的键值对,是比较好解析,我们可以直接利用 req.getParameter () 直接解析

而对于json,java并不能很好的解析出内容,所以我们需要使用第三方库:

Jackson

Maven Repository: com.fasterxml.jackson.core » jackson-databind » 2.13.4 (mvnrepository.com)

跟我们之前一样的进行引入依赖.即可

Jackson的使用也比较简单:需要两步:

  • 将json格式的字符串转成java对象.

  • 把java对象转成json字符串

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
class Student{
    public String Studentid;
    public String Classid;
}
@WebServlet("/jacksontest")
public class jacksontest extends Helloservlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);
        resp.getWriter().write(student.Classid+","+student.Studentid);
        resp.getWriter().write(objectMapper.writeValueAsString(student));
    }
}

利用ObjectMapper的实例化对象中的实例方法readValue可以将HTTP请求的body内容解析成对应的java对象(注意java对象中的属性名需要与body中的键值对键保持一致)

而writeValueAsString可以将java对象重新转成json数据.

HttpServletResponse

方法简介
void setStatus(int sc)为该响应设置状态码
void setHeader(String name,String value)设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值
void addHeader(String name, String value)添加一个带有给定的名称和值的 header. 如果 name 已经存在,不覆盖旧的值, 并列添加新的键值对
void setContentType(String type)设置被发送到客户端的响应的内容类型。
void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8
void sendRedirect(String location)使用指定的重定向位置 URL 发送临时重定向响应到客户端
PrintWriter getWriter()用于往 body 中写入文本格式数据.
OutputStream getOutputStream()用于往 body 中写入二进制格式数据.

代码案例:

自我刷新页面
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/example")
public class eample extends Helloservlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html; charset=utf8");
        resp.setHeader("Refresh","1");
        resp.getWriter().write("当前时间"+System.currentTimeMillis());

    }
}

设置响应报文的header内容 :

设置键值对: Refresh + 时间.

重定向
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/example")
public class eample extends Helloservlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html; charset=utf8");


        //第一种方式
        resp.setStatus(302);
        resp.setHeader("Location","http://www.sougou.com");
        //第二种方式
        resp.sendRedirect("http://www.sougou.com");
    }
}

这样在header 中设置状态码写入Location 即可完成重定向

直接使用sendRedirect也可以实现.

实现一个表白墙网页

准备工作:

  • 创建项目

  • 创建目录

  • 引入依赖

  • 将表白墙前端页面拷贝到项目中

    前端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>表白墙</title>
        <style>
            * {
                padding: 0;
                margin: 0;
                box-sizing: border-box;
            }
    
            .container {
                width: 800px;
                margin: 10px auto;
            }
    
            .container h2 {
                text-align: center;
                margin: 30px 0px;
            }
    
            .row {
                height: 50px;
                display: flex;
                justify-content: center;
                margin-top: 5px;
                line-height: 50px;
            }
    
            .row span {
                height: 50px;
                width: 100px;
                line-height: 50px;
            }
    
            .row input {
                height: 50px;
                width: 300px;
                line-height: 50px;
            }
    
            .row button {
                width: 400px;
                height: 50px;
                color: white;
                background-color: orange;
                border: none;
                border-radius: 10px;
            }
    
            .row button:active {
                background-color: grey;
            }
        </style>
    </head>
    <body>
        <!-- 这是一个顶层容器, 放其他元素 -->
        <div class="container">
            <h2>表白墙</h2>
            <div class="row">
                <span></span>
                <input type="text" id="from">
            </div>
    
            <div class="row">
                <span>对谁</span>
                <input type="text" id="to">
            </div>
    
            <div class="row">
                <span>说什么</span>
                <input type="text" id="message">
            </div>
    
            <div class="row">
                <button>提交</button>
            </div>
        </div>
    
        <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
        <script>
            let container = document.querySelector('.container');
            let fromInput = document.querySelector('#from');
            let toInput = document.querySelector('#to');
            let messageInput = document.querySelector('#message');
            let button = document.querySelector('button');
            button.onclick = function() {
                // 1. 把用户输入的内容获取到. 
                let from = fromInput.value;
                let to = toInput.value;
                let message = messageInput.value;
                if (from == '' || to == '' || message == '') {
                    return;
                }
                // 2. 构造一个 div, 把这个 div 插入到 .container 的末尾
                let newDiv = document.createElement('div');
                newDiv.className = 'row';
                newDiv.innerHTML = from + " 对 " + to + " 说: " + message;
                // 3. 把 div 挂在 container 里面
                container.appendChild(newDiv);
                // 4. 把之前的输入框内容进行清空
                fromInput.value = '';
                toInput.value = '';
                messageInput.value = '';
            }
        </script>
    </body>
    </html>
    

确定前后端交互信息:

我们在写后端代码之前,需要约定好,后端给前端的数据是什么样的,前端返回给后端的数据是什么样的.

我们的表白墙需要保证:

用户加载页面时,前端从后端拿到数据,我们可以约定

请求为: GET/message

响应我们使用json组织.

{
    {
        "from" : "狗",
        "to" : "猫",
        "sad" : "汪汪汪"
    }
    {   
        "from" : "猫",
        "to" : "狗",
        "sad" : "喵喵喵"
    }
}

用户点击提交后,后端从前端页面拿到数据:我们约定

请求为: POST/message

使用json组织

{
    {
        "from" : "狗",
        "to" : "猫",
        "sad" : "汪汪汪"
    }
    {   
        "from" : "猫",
        "to" : "狗",
        "sad" : "喵喵喵"
    }
}

响应使用标记来表示拿取成功与否:

{
    "ok": 1  //使用1表示成功,0表示失败
}

实现提交数据:

前端构造请求:

我们需要实现,点击提交按钮之后,后端为我们的前端能保存数据,下次刷新页面时,数据还存在.

        let messageexample = {
            "from" : from,
            "to" : to,
            "message" : message
        };
        $.ajax({
            type:'post',
            url:'message',
            contentType: 'application/json;charset=utf8',
            data:JSON.stringify(messageexample),
            success: function(body){
                alert("提交成功");
            },
            error : function(body){
                alert("提交失败");

            }
        })   

后端保存数据:

    ObjectMapper objectMapper = new ObjectMapper();
    List<Message> list = new ArrayList<>();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Message message1 = objectMapper.readValue(req.getInputStream(),Message.class);
        list.add(message1);
        System.out.println("message: " + message1);
        resp.setContentType("application/json;charset:uft8");
        resp.getWriter().write("{\"ok\" : 1}");

    }

实现返回数据

我们再每一次刷新或者提交数据之后,页面都能保存下我们的数据.这个时候需要后端向前端返回我们之前保存的数据.

前端构造请求:

     function load(){
        $.ajax({
            type:'get',
            url:'message',
            success: function(body){
                let container = document.querySelector('.container');
                for(let message of body){
                    let newDiv = document.createElement('div');
                    newDiv.className = 'row';
                    newDiv.innerHTML = message.from + "对" + message.to + "说" + message.message;
                    container.appendChild(newDiv);
                }
            }
        })

    };
    load();

后端返回数据:

 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
        //拿到数据并返回给前端
        String str = objectMapper.writeValueAsString(list);
        System.out.println(str);
        resp.getWriter().write(str);

    }

实现数据库版本

我们上面这个网站,如果把我们的服务器关闭,数据也就不见了.要想永久保留数据,就要将数据保存到数据库中.

引入数据库依赖:

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.17</version>
        </dependency>

在数据库中创建对应的数据库.这里自己在mysql创建即可,不多赘述了.

create database messagewall;
create table message('from' varchar(100),'to' varchar(100),message varchar(100));

实现JDBC 连接数据库,(这里使用单例模式实现)

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DButil {
    private static DataSource dataSource = null;
    public  static DataSource getDataSource(){
        if(dataSource==null){
            dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/MessageWall?characterEncoding=utf8&useSSL=false");
            ((MysqlDataSource)dataSource).setUrl("root");
            ((MysqlDataSource)dataSource).setPassword("123456");
        }
        return dataSource;
    }
    public static Connection getConnection() throws SQLException {
        return (Connection) getDataSource().getConnection();
    }
    public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement!=null){
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

在后端实现从数据库拿到数据并且返回给前端.

    public void save(Message message){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = DButil.getConnection();
            String sql = "insert into message values(?,?,?)";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,message.form);
            preparedStatement.setString(2,message.to);
            preparedStatement.setString(3,message.message);
            int ret = preparedStatement.executeUpdate();
            if(ret == 1){
                System.out.println("执行成功");
            }else{
                System.out.println("执行失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DButil.close(connection,preparedStatement,null);
        }

    }
    public List<Message> load(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Message> list = new ArrayList<>();
        try{
            connection = DButil.getConnection();
            String sql = "select * from Message";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while(resultSet.next()){
                Message message = new Message();
                message.form = resultSet.getString("form");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                list.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(connection,preparedStatement,resultSet);
        }
        return list;
    }
}

完整代码:

JavaEE-初阶: javaee初阶学习 - Gitee.com

cookie与session

我们在上文就已经得知,cookie是HTTP协议提供的一种维持数据持久化的机制,

cookie按照域名来分类,并且只能存储简单的键值对.

cookie的数据不是由浏览器来决定的,而是由服务器决定,当服务器返回的响应中有set-cookie时,浏览器才会给网页设置cookie.

设置玩cookie之后,浏览器每一次访问服务器,都会将cookie一并发送给服务器.

最典型的应用就是存储网页的个人用户信息.来做到避免需要多次重复输入登录.

而存储个人用户信息,我们并不好直接把用户信息存入到cookie中去,这样会导致信息泄露与不安全.

所以服务器实现了session,session也是键值对,其中sessionId为键,用户的个人信息为值.

当客户端向服务器发送登录请求(账号+密码) ,服务器会对身份进行校验,校验成功之后再进一步分配session,并且生成一个随机的sessionId作为key,将用户的信息作为value来构成键值对.完成以上工作之后,将sessionId返回给客户端作为cookie.

下一次客户端访问服务器时,会将sessionid一并发送给服务器,服务器通过sessionid即可在数据库中找到用户的个人信息.

cookie和seesion的区别:

  • cookie 是客户端的机制, session 是服务器的机制

  • cookie 和 seesion是经常搭配使用的,但也可以不搭配

    例如cookie可以只用来存储数据,不一定存储seesionid等服务器校验数据.

    seesion中的sessionid也并不一定就得通过cookie来传递.

在这里插入图片描述

Servlet中相关类与方法.

HttpServletRequest
  • HttpSession getSession()

    在服务器中获取会话,如果参数为true,则不存在会话时,创建新的会话(即创建新的HttpSession作为value,生成一个随机的sessionid作为键,保存在服务器的哈希表中).如果参数为false,则不存在会话时,直接返回null.

  • Cookie[] getCookie()

    返回一个cookie数组,包含客户端发送该请求的所有cookie值,并且将cookie中的值全部解析为键值对的方式.

HttpServletResponse
  • void addCookie(Cookie cookie)

    把指定的cookie添加到响应中

HttpSession
  • Object getAttribute(String name)

    该方法返回在该 session 会话中具有指定名称的对象,如果没

    有指定名称的对象,则返回 null.

  • void setAttribute(String name, Object value)

    该方法使用指定的名称绑定一个对象到该 session 会话

  • boolean isNew()

    判定当前是否是新创建出的会话

实现一个登录页面

我们通过上述方法来做到用户信息的保存.

前端页面:

 <!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登录页</title>
</head>
<body>
<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

创键Index,后端显示登录成功的用户名和登录次数

package login;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        if(session == null){
            //用户未登录
            resp.sendRedirect("login.html");
            return;
        }
        String name = (String)session.getAttribute("username");
        Integer visitcount = (Integer) session.getAttribute("visitcount");
        visitcount = visitcount+1;
        session.setAttribute("visitcount",visitcount);
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("当前用户为"+name+"访问次数"+visitcount);

    }
}

创建login,来处理前端请求,校验身份并且生成session.

package login;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        String name = req.getParameter("username");
        String password = req.getParameter("password");
        if(name==null||name.equals("")||password==null||password.equals("")){
            resp.getWriter().write("用户名登录或者密码格式错误,登录失败");
            return;
        }
        if(!password.equals("1234")&&!name.equals("libai")){
            resp.getWriter().write("用户名或者密码错误,登录失败");
            return;
        }
        HttpSession session = req.getSession(true);
        session.setAttribute("username",name);
        session.setAttribute("password",password);
        Integer visitcount = (Integer) session.getAttribute("visitcount");
        if(visitcount==null){
            session.setAttribute("visitcount",0);
        }else{

        }
        resp.sendRedirect("index");

    }
}

使用Servlet上传文件.

相关方法与类

HttpServletRequest
  • Part getPart(String name)

    获取请求中给定name的文件

  • Collection getParts()

    获取请求中的所有文件

Part类方法
  • String getSubmittedFileName()

    获取提交的文件名

  • String getContentType()

    获取提交的文件的文件类型

  • long getsize()

    获取文件的大小

  • void write(String path)

    把提交的文件写入磁盘

实现一个上传文件页面

前端页面:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>上传文件页</title>
</head>
<body>
<form action="load" method="post" enctype="multipart/form-data">
    <input type="file" name = "myfile">
    <input type="submit" value="提交">
</form>
</body>
</html>

注意这里的enctype=“multipart/form-data”,这个属性是单独给"上传文件设置的",他会设置ContentType,并且为文件设置文件的结束标志.

后端代码:

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
@MultipartConfig
@WebServlet("/load")
public class upload extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Part part = req.getPart("myfile");
        System.out.println(part.getSubmittedFileName());
        System.out.println(part.getSize());
        System.out.println(part.getContentType());
        part.write("D:/result.jpg");
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("成功");
    }
}

@MultipartCon 这个注解是上传文件的后端代码必须加的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小连~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值