Java之Servlet API

HttpServlet

处理GET请求

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 {
        //这行代码要注释掉,不能调用父类的doget
       // super.doGet(req, resp);

        //这个是让服务器在自己的控制台打印
        System.out.println("hello  hello");
        //在页面上也打印 hello world,把hello world字符串,放到http响应的body中,浏览器就会把body的内容显示到页面上
        resp.getWriter().write("hello  hello");

    }
}

处理POST请求

@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doPost(req, resp);
        resp.setContentType("test/html;charset=utf8");
        resp.getWriter().write("POST响应");
    }
}
<body>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        $.ajax({
            type:'post',
            url:'method',
            success:function(body){
                console.log(body);
                

            }

        });
    </script>

</body>

在这里插入图片描述

执行结果:
在这里插入图片描述

HttpServletRequest

HttpServletRequest对应到一个HTTP请求,HTTP请求中有啥,这里就有啥。

核心方法

在这里插入图片描述

打印请求信息

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;
import java.util.Enumeration;

@WebServlet("/showRequest")
public class showRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //调用下刚才涉及到的API,并且把得到的结果组织到一个html中,并作为响应的body

       //把api执行的结果,放到stringBuilder中
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("<h3>首行 部分</h3>");
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        stringBuilder.append("<h3>header 部分</h3>");
        Enumeration<String> headerNames=req.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName=headerNames.nextElement();
            String headerValue= req.getHeader(headerName);
            stringBuilder.append(headerName+": "+headerValue+"<br>");
        }
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(stringBuilder.toString());

    }
}

结果:
在这里插入图片描述

获取GET请求中的参数

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("/getParameter")
public class getParameterServlet extends HttpServlet {
    //预期浏览器传来一个形容这样的请求:/getParameter?userId=123&classId=456
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      String userId=req.getParameter("userId");
      String classId=req.getParameter("classId");
      resp.getWriter().write("userId="+userId+", classId="+classId);
  }


}

这里是引用

获取POST请求中的参数

POST请求中的参数一般通过body传递给服务器。
POST请求body格式
(1)x-www-form-urlencoded
(2)form-data
(3)json
1.如果请求是x-www-form-urlencoded这种格式,服务器如何获取参数呢?
获取参数的方式和GET一样,也是getParameter
在前端通过form表单构造请求

在这里插入代码片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("/postGetParameter")
public class PostGetParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //假设前端传过来的参数是userId=10&classId=20
        //服务器也是通过req.getParameter来获取到内容
        String userId=req.getParameter("userId");
        String classId=req.getParameter("classId");
        resp.getWriter().write("userId="+userId+",classId="+classId);
    }
}

<body>
    <form action="postGetParameter" method="POST">
        <input type="text" name="userId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        // $.ajax({
        //     type:'post',
        //     url:'method',
        //     success:function(body){
        //         console.log(body);
                

        //     }

        // });
    </script>



</body>

在这里插入图片描述

这里是引用

2.如果请求是json的方式,该如何处理?
可以通过第三方库,直接处理json格式数据。

{
    userId:1234,
    classId:5678
    }

对于如上的body为json的格式来说,如果手动解析,其实并不容易

主要使用的库,叫做Jackson.
通过maven把Jackson这个库,下载到本地,并引入到项目中。
在这里插入图片描述
在这里插入图片描述
(一)在浏览器前端代码中,通过JS构造出body为json格式的请求

<input type="text" id="userId">
<input type="text" id="classId">
<input type="button" value="提交" id="submit">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
     let userIdinput=document.querySelector("#userId");
        let classIdinput=document.querySelector("#classId");
        let button=document.querySelector("#submit");
        button.onclick=function(){
            $.ajax({
                type:'post',
                url:'postJson',
                contentType:'application/json',
                data:JSON.stringify({
                    userId:userIdinput.value,
                    classId:classIdinput.value

                }),
                success:function(body){
                    console.log(body);
                    
                }



            });


        }
    </script>
        

(二)在Java后端代码中,通过Jackson进行处理。

import com.fasterxml.jackson.databind.ObjectMapper;

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;
class User {
    public int userId;
    public int classId;

}
@WebServlet("/postJson")
public class PostJsonServlet extends HttpServlet {
    //1.创建一个Jackson的核心对象
    private ObjectMapper objectMapper=new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //2.读取body中的请求,然后使用objectMapper来解析成需要的对象
        //readValue就是把json格式的字符串,转成Java的对象
        //第一个参数,表示对哪个字符串进行转换,这个参数可以填写成一个String,也可以填写成一个InputStream对象,还可以填File
        //第二个参数,表示 要把这个json格式的字符串,转成哪个Java对象
        User user=objectMapper.readValue(req.getInputStream(),User.class);
        resp.getWriter().write("userId:"+user.userId+",classId"+user.classId);




    }
}

结果:这里是引用
在这里插入图片描述
点击提交之后,可以看到,在浏览器控制台中,就打印出来了服务器的响应数据。当前使用的是ajax的方式来提交数据,这个操作默认不会产生页面跳转,就和使用form风格差别很大。

HttpServletResponse

HttpServletResponse对应到一个HTTP响应,HTTP响应里有
啥,这里就有啥。

核心方法

在这里插入图片描述

设置状态码

200

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("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.getWriter().write("hello");
    }
}

通过fiddler抓包,可以看到结果这里是引用

404

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(404);
        resp.getWriter().write("hello");
    }
}

这里是引用

自动刷新

给http响应中设置一个header.Refresh

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("/autoRefresh")
public class AutoRefresh extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh","1");
        resp.getWriter().write("timeStamp:"+System.currentTimeMillis());

    }
}

重定向

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("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在这里返回一个302重定向响应,让浏览器自动跳转到 搜狗主页
        resp.setStatus(302);
        resp.setHeader("Location","https://www.sogou.com/");
    }
}

更简单的用法

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在这里返回一个302重定向响应,让浏览器自动跳转到 搜狗主页
       resp.sendRedirect("https:www.baidu.com");
    }
}

服务器版本的表白墙

在这里插入图片描述

之前实现的表白墙,页面一刷新,内容就不存在了,因此可以通过服务器,来保存数据,从而做到“持久化”存储。

在实现这个程序的时候,就需要先考虑客户端和服务器该如何进行交互。
也就是要约定前后端交互接口。

对表白墙来说,主要提供两个接口。
1.告诉服务器,当前留言了一条啥样的数据
(当用户点击提交按钮的时候,就会给服务器发送一个HTTP请求,让服务器把这个消息存下来)
2.从服务器获取到,当前都有哪些留言数据。(当页面加载的时候,就需要从服务器获取到曾经存储的这些消息内容)

import com.fasterxml.jackson.databind.ObjectMapper;

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;
import java.util.ArrayList;
import java.util.List;

class Message {
    public String from;
    public String to;
    public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper=new ObjectMapper();

    private List<Message> messages=new ArrayList<>();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理提交消息的请求
       Message message= objectMapper.readValue(req.getInputStream(),Message.class);
      //最简单的保存方法是保存到内存中
       messages.add(message);
       //通过ContentType告知页面,返回的数据是json格式
       resp.setContentType("application/json;charset=utf8");
       resp.getWriter().write("{\"ok\":true}");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取到消息列表,只要把消息列表内容整个给返回客户端即可
        //此处需要使用objectMapper把Java对象,转成json格式字符串

        String jsonString=objectMapper.writeValueAsString(messages);
        System.out.println("jsonString: " + jsonString);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonString);
    }


}
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
    //   加入ajax的代码,此处要加入的逻辑有两个部分
    //   点击提交按钮的时候,ajax要能够构造数据发送给服务器
    //   页面加载的时候,从服务器获取消息列表,并在界面上直接显示 
        function getMessages(){
            $.ajax({
                type:'get',
                url:'message',
                success:function(body){
                  //当前的body已经是一个JS对象数组了,ajax会根据响应的content type来自动进行解析
                  //如果服务器返回的content type已经是application/json了,ajax就会把body自动转成JS的对象
                  //如果客户端没有自动转,也可以通过JSON.parse()来手动转换
                    let container=document.querySelector('.container');
                    for(let message of body){
                        let div=document.createElement('div');
                        div.innerHTML=message.from+'对'+message.to+'说:'+message.message;
                        div.className='row';
                        container.appendChild(div);

                    }

                }

            });
        }
        //函数调用
        getMessages();

    
        //当用户点击submit,就会获取到input中的内容,从而把内容构造成一个div,插入到页面的末尾
        let submitBtn=document.querySelector('#submit');
        submitBtn.onclick=function() {
            //1.先获取到3个input中的内容
            let inputs=document.querySelectorAll('input');
            let from=inputs[0].value;
            let to=inputs[1].value;
            let msg=inputs[2].value;
            if(from=='' || to=='' || msg==''){
                //用户还没填写完事,暂时先不提交数据
                return;
            }
            //2.生成新的div,内容就是input里的内容,把这个新的div加到页面中
            let div=document.createElement('div');
            div.innerHTML=from+'对'+to+'说:'+msg;
            div.className='row';
            let container=document.querySelector('.container');
            container.appendChild(div);
            //3.清空之前输入框的内容
            for(let i=0;i<inputs.length;i++){
                inputs[i].value='';
            }
            //4. 把把当前获取到的输入框的内容,构造成一个HTTP POST请求,通过ajax发给服务器
            let body={
                from:from,
                to:to,
                message:msg
            };
            $.ajax({
                type:"post",
                url:"message",
                contentType:"application/json;charset=utf8",
                data:JSON.stringify(body),
                success:function(body){
                    alert("消息提交成功");
                },
                error:function(){
                    alert("消息提交失败");
                }
            });



        }
    </script>

对象和json字符串之间的转换
Java:
objectMapper.readValue:把json字符串转成对象
objectMapper.writeValue:把对象转成json字符串
JS:
json.parse:把json字符串转成对象
json.stringify:把对象转成json字符串

刷新页面,数据确实还在,但是重新启动服务器,数据就不存在了,因此需要把数据保存在硬盘上。

使用JDBC基本流程:

  1. 创建数据源
  2. 和数据库建立连接
  3. 构造SQL语句
  4. 执行SQL语句
  5. 如果是查询语句,需要遍历结果集,如果是插入/ 删除 /修改,则不需要
  6. 关闭连接,释放资源

部分源码:

private void save(Message message){
        //把一条消息保存在数据库中
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //1.与数据库建立连接
             connection=DBUtil.getConnection();
            //2.构造SQL
            String sql="insert into message values(?,?,?)";
             statement=connection.prepareStatement(sql);
            statement.setString(1,message.from);
            statement.setString(2,message.to);
            statement.setString(3,message.message);
            //3.执行sql
            statement.executeUpdate();
            //4.释放资源

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }

    private List<Message> load(){
        List<Message> messages=new ArrayList<>();
        //从数据库中获取到所有的消息
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from message";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();
            while(resultSet.next()){
                Message message=new Message();
                message.from=resultSet.getString("from");
                message.to=resultSet.getString("to");
                message.message=resultSet.getString("message");
                messages.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return  messages;
    }
public class DBUtil {
    private static final String URL="jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false";
    private static  final  String USERNAME="root";
    private static  final  String PASSWORD="999990";
    private volatile static DataSource dataSource = null;

    private  static DataSource getDataSource() {
        if(dataSource == null){
            synchronized (DBUtil.class){
                if(dataSource==null) {
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setURL(URL);
                    ((MysqlDataSource)dataSource).setUser(USERNAME);
                    ((MysqlDataSource)dataSource).setPassword(PASSWORD);
                }
            }
        }


        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

开发表白墙的基本步骤:
(1)约定前后端交互接口(请求是啥,响应是啥)
(2)开发服务器代码
先编写Servlet能够处理前端发来的请求
编写数据库代码,来存储/获取关键数据
(3)开发客户端代码
基于ajax能够构造请求以及解析响应
能够响应用户的操作(点击按钮之后,触发给服务器发送请求的行为)

MVC
Model(操作数据存取的逻辑)
View(给用户展示的界面)
Controller(控制器,处理请求之后的关键逻辑)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值