后台(12)——Servlet(4)

简介: 探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制Android多分...

探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南


自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


版权声明


在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest

HttpServletRequest的简单使用

HttpServletRequest代表客户端的请求,当客户端通过HTTP协议访问服务器时与请求相关的所有信息都将被封装在这个对象中,所以我们可通过该对象获得客户端的相关信息。

常用的方法如下:

  • getRequestURL():返回客户端发出请求时的完整URL
  • getRequestURI():返回请求行中的资源名部分
  • getContextPath():返回请求的上下文路径
  • getQueryString():返回请求行中的参数部分
  • getParameter():返回参数中的具体值
  • getRemoteAddr():返回发出请求的客户端的IP地址
  • getRemoteHost():返回发出请求的客户端的完整主机名
  • getRemotePort():返回客户端所使用的网络端口号
  • getMethod():返回客户端使用的请求方式
  • getHeaderNames():返回此请求包含的所有头的名称
  • getHeader():返回指定的请求头的值

请看如下示例:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

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

public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        getRequestInfo(request);
        getRequestHeader(request);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    }

    //获取与请求相关的信息
    private void getRequestInfo(HttpServletRequest request){
        String method=request.getMethod();
        StringBuffer requestURL = request.getRequestURL();
        String requestURI = request.getRequestURI();
        String contextPath = request.getContextPath();
        String queryString = request.getQueryString();
        String name=request.getParameter("name");
        String remoteAddr = request.getRemoteAddr();
        String remoteHost = request.getRemoteHost();
        int remotePort = request.getRemotePort();
        System.out.println("----> method="+method);
        System.out.println("----> requestURL="+requestURL);
        System.out.println("----> requestURI="+requestURI);
        System.out.println("----> contextPath="+contextPath);
        System.out.println("----> queryString="+queryString);   
        System.out.println("----> remoteAddr="+remoteAddr);
        System.out.println("----> remoteHost="+remoteHost);
        System.out.println("----> remotePort="+remotePort);
    }

    //获取请求的Header中的信息
    private void getRequestHeader(HttpServletRequest request){
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String headKey=headerNames.nextElement();
            String headValue=request.getHeader(headKey);
            System.out.println(headKey+":"+headValue);
        }       
    }
}

代码写好了,我们现在通过浏览器发出请求:

http://localhost:8081/TestServlet03/helloServlet?name=lucy

在Console中观察输入结果:

—-> method=GET
—-> requestURL=http://localhost:8081/TestServlet03/helloServlet
—-> requestURI=/TestServlet03/helloServlet
—-> contextPath=/TestServlet03
—-> queryString=name=lucy
—-> name=lucy
—-> remoteAddr=127.0.0.1
—-> remoteHost=127.0.0.1
—-> remotePort=63484
host:localhost:8081
connection:keep-alive
cache-control:max-age=0
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 10.0;Win64; x64)Chrome/47.0.2526.111
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8

嗯哼,结合这些输出结果再回过头看这些方法就能有更好的体会。在此,再次强调一下:请注意getRequestURL()和getRequestURI()以及getContextPath()、getQueryString()这四个方法的区别

  • getRequestURL()返回的是请求的路径,但是不含请求的参数部分
  • getRequestURI()返回请求行中的资源名部分,但是不含有请求的主机和端口以及请求的参数部分
  • getContextPath()返回请求的上下文,即/+项目名称,比如此处的/TestServlet03

在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest

HttpServletRequest处理表单请求

在刚才的示例中,我们利用getParameter()获取GET请求中请求参数中的具体值,那么在POST请求时又该怎么获取传递给服务端的值呢?请看如下示例

先准备一个表单:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome</title>
</head>
<body>
    <form action="/TestServlet03/form" method="post">
        用 户:<input type="text" name="username"/>
              <br/><br/>
        密 码:<input type="password" name="password"/>
             <br/><br/>
        性 别:<input type="radio" name="gender" value="男" /><input type="radio" name="gender" value="女" checked="checked"/><br/><br/>
        爱 好:<input type="checkbox" name="hobby" value="摄影"/>摄影
             <input type="checkbox" name="hobby" value="唱歌"/>唱歌
             <input type="checkbox" name="hobby" value="拍照"/>拍照
             <br/><br/>
        城 市:
        <select name="city">
            <option>------请选择------</option>
            <option value="dj">东京</option>
            <option value="db">大阪</option>
            <option value="xt">仙台</option>
        </select>
        <br/><br/>
        <input type="submit" value="欢迎注册VIP会员"/>
    </form>
</body>
</html>

再实现服务端的代码:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

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

public class TestForm extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        testForm1(request);
    }

    private void testForm1(HttpServletRequest request)throws ServletException,IOException {
        request.setCharacterEncoding("UTF-8");
        Enumeration<String> parameterNames = request.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String[] values = request.getParameterValues(name);
            for(int i=0;values!=null&&i<values.length;i++){
                System.out.println("name="+name+" "+"value="+values[i]);
            }
        }
    }
}

代码解析如下:

  • 利用setCharacterEncoding()设置编码方式
  • 利用getParameterNames()获取所有请求参数的名称,请参见代码第28行
    对于此处的表单POST提交而言传递的参数的名称分别为username,password,gender,hobby,city
  • 获取每个参数对于的值,请参见代码第29-35行

嗯哼,现在我们通过浏览器来发起一个请求:

这里写图片描述

在Console观察打印信息:

name=username value=杉原杏璃
name=password value=123456789
name=gender value=女
name=hobby value=摄影 name=hobby value=拍照
name=city value=dj

在实际开发中,我们可能需要将这些传递给服务端的信息封装成实体,请看如下示例:

先准备一个实体Entity:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

import java.io.Serializable;
import java.util.Arrays;

public class User implements Serializable{
    private String username;
    private String password;
    private String gender;
    private String[] hobby;
    private String city;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String[] getHobby() {
        return hobby;
    }
    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password
                + ", gender=" + gender + ", hobby=" + Arrays.toString(hobby)
                + ", city=" + city + "]";
    }

}

请注意,该实体中字段的名字必须与表单中各个name的值相对应

再来看服务端的代码:

private void testForm2(HttpServletRequest request)throws ServletException,IOException {
        try {
            request.setCharacterEncoding("UTF-8");
            User user = new User();
            Map<String,String[]> parameterMap = request.getParameterMap();
            for (Map.Entry<String, String[]> map : parameterMap.entrySet()) {
                String name = map.getKey();
                String[] values = map.getValue();
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, User.class);
                Method method = propertyDescriptor.getWriteMethod();
                if(values.length==1&&!name.equals("hobby")){
                    method.invoke(user, values[0]);
                }else{
                    method.invoke(user, (Object)values);
                }
            }

            System.out.println("------> "+user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

代码解析如下:

  • 利用getParameterMap()得到请求中所有的参数及其对应的值,请参见代码第5行
    注意:有的参数只有一个值,比如该示例中的username;有的参数会有多个值,比如该示例中的hobby
  • 获取每个参数及其对应的值,请参见代码第7-8行
  • 反射出每个参数在实体中的setter()方法,请参见代码第9-10行
  • 设置每个参数对应的值,请参见代码第11-15行

请求重定向与请求转发的区别

我们知道:

  • 利用response.sendRedirect()实现请求的重定向
  • 利用request.getRequestDispatcher().forward()实现请求的转发

请注意它们的区别:

  • 重定向时浏览器中的地址栏会发生变化,但是请求转发时浏览器中地址栏不会发生改变。从本质上来讲:重定向是两次不同的请求,而请求转发只向服务端的发送了一次请求由服务端的内部实现请求的跳转。
  • 重定向可以跳转到应用的外部,而重定向的范围只能是应用的内部
  • 请求转发可利用request.setAttribute()将数据传递到下一个Servlet且下一个Servlet可用request.getAttribute()取出数据;但是重定向不可以也没有道理这么做。至于为什么,请参考第一点。
相关文章
|
3月前
|
前端开发 JavaScript BI
基于Servlet房屋租赁管理信息系统(含前后台)(Java+Servlet+jsp+mysql)
基于Servlet房屋租赁管理信息系统(含前后台)(Java+Servlet+jsp+mysql)
|
3月前
|
Java 数据库 数据安全/隐私保护
基于Servlet+Jsp实现的酒店客房预定管理系统分前后台
基于Servlet+Jsp实现的酒店客房预定管理系统分前后台
|
3月前
|
Java 关系型数据库 MySQL
基于servlet+jsp实现的电影院订票系统分前后台
基于servlet+jsp实现的电影院订票系统分前后台
编写后台 Servlet
编写后台 Servlet
34 0
编写后台 Servlet
编写后台 Servlet
45 0
|
Java 应用服务中间件 Android开发
servlet前后端交互-----解决java WEB中前台传数据到后台中文乱码问题的最简单方法
servlet前后端交互-----解决java WEB中前台传数据到后台中文乱码问题的最简单方法
216 0
servlet前后端交互-----解决java WEB中前台传数据到后台中文乱码问题的最简单方法
原来后台是这样分辨浏览器请求的 浏览器发送请求给服务器 服务器通过反射辨别Servlet类 通过methodName分辨方法 妈妈再也不用担心我的学习了
原来后台是这样分辨浏览器请求的 浏览器发送请求给服务器 服务器通过反射辨别Servlet类 通过methodName分辨方法 妈妈再也不用担心我的学习了
171 0
|
SQL 前端开发 JavaScript
关于使用jquery的Ajax结合java的Servlet后台判定用户名是否存在
关于把AJAX加入到注册登录demo中去 2018年3月10日 19:21:23 第一次来SUBWAY真切地打代码. 这次的西红柿汤还是挺好喝的. index.jsp: ajax测试 $(function () { $("#loginName").
1234 0
|
Web App开发 JavaScript 前端开发
基于jsp+servlet图书管理系统之后台用户信息插入操作
前奏:   刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识。于是静下心来钻研知识,趁着这学期的结束(马上就要放寒假了),写写最近练习的基于jsp+servlet+前台模板写的图书管理系统,一点一点写吧,详细的注释已经在代码上说明,希望对学习基于java开发的web方
3104 0
|
SQL JavaScript Java
基于jsp+servlet图书管理系统之后台用户信息修改操作
上一篇的博客写的是查询操作,且附有源码和数据库,这篇博客写的是修改操作,附有从头至尾写的代码(详细的注释)和数据库!   此次修改操作的源码和数据库:http://download.csdn.net/detail/biexiansheng/9732691  为了方便理解和说明,先写一下执行的流程和步奏,详细代码可以下载连接。   1:修改操作的执行流程:     1.1:修改操作需要
2617 0