Servlet

Servlet

Servlet简介

  • Servlet就是sun公司开发动态web的一门技术
  • Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中。

把实现了Servlet接口的Java程序叫做,Servlet

HelloServlet

构建一个普通的Maven项目, 删掉 src,以后我们的学习,就在项目中建立Moudle

关于Maven父子工程的理解

父项目中会有:

<modules>
    <module>servlet-01</module>
</modules>

子项目中会有:

<parent>
    <artifactid>javaweb-02-servlet</artifactid>
    <groupid>com.zhu</groupid>
    <version>1.0-SNAPSHOT</version>
</parent>

Maven 环境优化

  1. 修改web.xml为最新
  2. 将maven的结构搭建完整
<!--?xml version="1.0" encoding="UTF-8"?-->
<!--Servlet 3.0 的部署描述文件 web.xml 的顶层标签 <web-app> 有一个 metadata-complete 属性,
该属性指定当前的部署描述文件是否是完全的。如果设置为 true,则容器在部署时将只依赖部署描述文件,
忽略所有的注解(同时也会跳过 web-fragment.xml 的扫描,亦即禁用可插性支持,具体请看后文关于 可插性支持的讲解);
如果不配置该属性,或者将其设置为 false,则表示启用注解支持(和可插性支持)-->

<web-app version="4.0" metadata-complete="true" 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_4_0.xsd">


</web-app>

编写一个servlet 程序

  1. 实现Servlet 接口 直接继承 HttpServlet
  2. 编写Serviet 的映射
    1. 为什么写映射: 我们写的是JAVA程序,但是要通过浏览器访问,浏览器需要连接web浏览器, 所以我们需要在web服务中注册我们写的Servlet 还需要给他一个浏览器能够访问的路径

导入父项目pom.xml依赖,子项目继承

<!--添加Servlet和JSP依赖-->
<dependency>
    <groupid>javax.servlet</groupid>
    <artifactid>javax.servlet-api</artifactid>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

父项目pom.xml

<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0      http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>

    <groupid>com.zhu</groupid>
    <artifactid>javaweb-02-servlet</artifactid>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>servlet-01</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>javax.servlet-api</artifactid>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

子项目pom.xml

<!--?xml version="1.0" encoding="UTF-8"?-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>

  <groupid>com.zhu</groupid>
  <artifactid>servlet-01</artifactid>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>servlet-01 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <parent>
    <artifactid>javaweb-02-servlet</artifactid>
    <groupid>com.zhu</groupid>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <properties>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupid>junit</groupid>
      <artifactid>junit</artifactid>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <finalname>servlet-01</finalname>
    <pluginmanagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactid>maven-clean-plugin</artifactid>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactid>maven-resources-plugin</artifactid>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactid>maven-compiler-plugin</artifactid>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactid>maven-surefire-plugin</artifactid>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactid>maven-war-plugin</artifactid>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactid>maven-install-plugin</artifactid>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactid>maven-deploy-plugin</artifactid>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginmanagement>
  </build>
</project>

编写servlet类继承HttpServlet

Servlet
public class HellowServlet extends HttpServlet {
    //由于gat或者post只是请求实现的不同方法,可以互相调用,业务逻辑一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();///响应流
        writer.println("HellowServlet");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

配置web.xml映射

<!--?xml version="1.0" encoding="UTF-8"?-->
<!--Servlet 3.0 的部署描述文件 web.xml 的顶层标签 <web-app> 有一个 metadata-complete 属性,
该属性指定当前的部署描述文件是否是完全的。如果设置为 true,则容器在部署时将只依赖部署描述文件,
忽略所有的注解(同时也会跳过 web-fragment.xml 的扫描,亦即禁用可插性支持,具体请看后文关于 可插性支持的讲解);
如果不配置该属性,或者将其设置为 false,则表示启用注解支持(和可插性支持)-->

<web-app version="4.0" metadata-complete="true" 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_4_0.xsd">

    <!--注册servlet-->
    <servlet>
        <servlet-name>hellow</servlet-name>
        <servlet-class>com.kuang.servlet.HellowServlet</servlet-class>
    </servlet>
    <!--  servlet请求路径-->
    <servlet-mapping>
        <servlet-name>hellow</servlet-name>
        <url-pattern>/hellow</url-pattern>
    </servlet-mapping>

</web-app>

注解方式

@WebServlet("/hi")
public class HelloServlet extends HttpServlet{
}
  • 配置tomcat

    注意配置项目发布的路径

  • 启动项目,访问路径

Servlet原理

Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:

Servlet

Mapping问题

一个Servlet可以指定一个映射路径

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

一个Servlet可以指定多个映射路径

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello3</url-pattern>

一个Servlet可以指定通用映射路径

  • /hello/* ——> /hello后边不管写啥都返回当前带哦用的servlet-name 的方法
  • /* 默认通配符
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
</servlet-mapping>

默认请求路径

<!--默认请求路径-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

优先级问题

<!--404-->
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用

共享数据

public class Serlvet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getServletConfig()  //servlrt 配置
        //this.getInitParameter()   //初始化参数
        //this.getServletContext();   //servlet上下文
        ServletContext contxt = this.getServletContext();
        String username = "JOBB"; //数据
        contxt.setAttribute("username",username);//将一个数据保存在了ServletContext中,  名字为: username 值: username
        System.out.println("欢迎");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
public class ReadSerlvet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据
        ServletContext context = this.getServletContext();
        String username = (String)context.getAttribute("username");
        //响应
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().println("姓名: "+username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml配置

<servlet>
    <servlet-name>setnum</servlet-name>
    <servlet-class>com.zhu.servlet.Serlvet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>setnum</servlet-name>
    <url-pattern>/Serlvet</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>get</servlet-name>
    <servlet-class>com.zhu.servlet.ReadSerlvet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>get</servlet-name>
    <url-pattern>/get</url-pattern>
</servlet-mapping>

必须先访问hello接口,然后访问get接口,才能获取name的值。

获取初始化参数

web.xml中配置

<!--Web的初始化配置-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>

java中

public class ServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        javax.servlet.ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().println(url);
    }
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

请求转发

jpublic class ServletrequestDispatcher extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入了ServletrequestDispatcher");
        ServletContext context = this.getServletContext();
        //RequestDispatcher url = context.getRequestDispatcher("/url");//转发路径 格式: /url  /路径
        //url.forward(req,resp);//调用forward 转发
        context.getRequestDispatcher("/url").forward(req,resp);//合写
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

读取资源文件

编写b.properties文件

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现: 都被打包到了同一路径下: classes,俗称为类路径

思路: 需要一个文件流;

username = Mack
id = 00001
passworld = 123456789
Servlet
public class ServletReadPropise extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.propise");
        Properties prop = new Properties();
        prop.load(is);
        String username = prop.getProperty("username");
        String id = prop.getProperty("id");
        String passworld = prop.getProperty("passworld");
        resp.getWriter().println(username+", "+passworld+", "+id);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp); 
    }
}

HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

简单分类

负责向浏览器发送数据的方法

ServletOutputStream getOutputStream()throwsIOException;//y
PrintWriter getWriter()throwsIOException;//一般中文用

负责向浏览器发送响应头的方法

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1,long var2);
void addDateHeader(String var1,long var2);
void setHeader(String var1,String var2);
void addHeader(String var1,String var2);
void setIntHeader(String var1,int var2);
void addIntHeader(String var1,int var2);

响应的状态码

int SC_CONTINUE =100;int SC_SWITCHING_PROTOCOLS =101;
int SC_OK =200;int SC_CREATED =201;int SC_ACCEPTED =202;int SC_NON_AUTHORITATIVE_INFORMATION =203;int SC_NO_CONTENT =204;int SC_RESET_CONTENT =205;int SC_PARTIAL_CONTENT =206;
int SC_MULTIPLE_CHOICES =300;int SC_MOVED_PERMANENTLY =301;int SC_MOVED_TEMPORARILY =302;int SC_FOUND =302;int SC_SEE_OTHER =303;int SC_NOT_MODIFIED =304;int SC_USE_PROXY =305;int SC_TEMPORARY_REDIRECT =307;
int SC_BAD_REQUEST =400;int SC_UNAUTHORIZED =401;int SC_PAYMENT_REQUIRED =402;int SC_FORBIDDEN =403;int SC_NOT_FOUND =404;int SC_METHOD_NOT_ALLOWED =405;int SC_NOT_ACCEPTABLE =406;int SC_PROXY_AUTHENTICATION_REQUIRED =407;int SC_REQUEST_TIMEOUT =408;int SC_CONFLICT =409;int SC_GONE =410;int SC_LENGTH_REQUIRED =411;int SC_PRECONDITION_FAILED =412;int SC_REQUEST_ENTITY_TOO_LARGE =413;int SC_REQUEST_URI_TOO_LONG =414;int SC_UNSUPPORTED_MEDIA_TYPE =415;int SC_REQUESTED_RANGE_NOT_SATISFIABLE =416;int SC_EXPECTATION_FAILED =417;
int SC_INTERNAL_SERVER_ERROR =500;int SC_NOT_IMPLEMENTED =501;int SC_BAD_GATEWAY =502;int SC_SERVICE_UNAVAILABLE =503;int SC_GATEWAY_TIMEOUT =504;int SC_HTTP_VERSION_NOT_SUPPORTED =505;
/*200:请求响应成功 200
3xx:请求重定向
- 重定向:你重新到我给你新位置去;
4xx:找不到资源 404
- 资源不存在;
5xx:服务器代码错误 500 502:网关错误
*/

常见应用

下载文件

  1. 要获取下载文件的路径
  2. 下载的文件名是啥?
  3. 设置想办法让浏览器能够支持下载我们需要的东西
  4. 获取下载文件的输入流
  5. 创建缓冲区
  6. 获取OutputStream对象
  7. 将FileOutputStream流写入到buffer缓冲区
  8. 使用OutputStream将缓冲区中的数据输出到客户端!
package com.zhu;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**

 * @author shkstart @create 2021-05-12 22:16
   */
   public class Servlet_04_FileDown extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   //        1. 要获取下载文件的路径
       String realPath = "D:\\IDEA_project\\JavaWeb\\response\\target\\classes\\60599be88322e6675c2d7c68.jpg";
       System.out.println("下载的文件的路径: "+realPath);
   //        2. 下载的文件名是啥?
       String filename = realPath.substring(realPath.indexOf("\\") + 1);
   //        3. 设置让浏览器能够支持"Content-Disposition"下载我们需要的东西
       resp.setHeader("Content-Disposition","attachment;filename= "+ URLEncoder.encode(filename,"UTF-8"));
   //        4. 获取下载文件的输入流
       FileInputStream in = new FileInputStream(realPath);
   //        5. 创建缓冲区
       int length = 0;
       byte[]buffer = new byte[1024];
   //        6. 获取OutputStream对象
       ServletOutputStream out= resp.getOutputStream();
   //        7. 将FileOutputStream流写入到buffer缓冲区
   //        8. 使用OutputStream将缓冲区中的数据输出到客户端!
       while ((length=in.read(buffer))>0){
           out.write(buffer,0,length);
       }
   //关闭流
       in.close();
       out.close();
   }
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       super.doGet(req, resp);
   }
   }

验证码功能

  • 前端实现
  • 后端实现,需要用到Java的图片类,生产一个图片
@WebServlet("/img")
public class ImageServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
    	//如何让浏览器3秒自动刷新一次;        
    	resp.setHeader("refresh","3");
        
        //在内存中创建一个图片
        BufferedImage image =newBufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g =(Graphics2D) image.getGraphics();//笔
        //设置图片的背景颜色        
        g.setColor(Color.white);        
        g.fillRect(0,0,80,20);
        //给图片写数据        
        g.setColor(Color.BLUE);        
        g.setFont(newFont(null,Font.BOLD,20));        
        g.drawString(makeNum(),0,20);

        //告诉浏览器,这个请求用图片的方式打开        
        resp.setContentType("image/jpeg");
        //网站存在缓存,不让浏览器缓存        
        resp.setDateHeader("expires",-1);        
        resp.setHeader("Cache-Control","no-cache");        
        resp.setHeader("Pragma","no-cache");

        //把图片写给浏览器
        ImageIO.write(image,"jpg", resp.getOutputStream());
    }
    
    //生成随机数
    private String makeNum(){
        Random random =newRandom();
    	String num = random.nextInt(9999999)+"";
        StringBuffer sb =newStringBuffer();
        for(int i =0; i <7-num.length(); i++){
            sb.append("0");}        
        num = sb.toString()+ num;
        return num;
    }
    
    @Override
    protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
        doGet(req, resp);
    } 
}

实现重定向

Servlet

B一个web资源收到客户端A请求后,B会通知A去访问另外一个web资源C,这个过程叫重定向。

常见场景

用户登录

void sendRedirect(String varl)throw IOException;

测试

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        
         */
        resp.setHeader("Location","/r/image");
        resp.setStatus(302);
        resp.sendRedirect("/r/image");//重定向
    }

重定向和转发的区别?

相同点: 页面都会跳转

不同点:

  • 请求转发 (307)url不会产生变化, 重定向(302)会发生变化
  • 请求转发 可以携带参数, 重定向不能携带参数
  • 请求转发 只能发送一个请求, 重定向至少发送两次请求

简单实现登录重定向

public class Servlet_06_RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入请求");
        //处理请求
        //从那个请求中获取参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username+" : "+password);
		//重定向时一定要注意路径问题  否则404
        resp.sendRedirect("/r/success.jsp");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!--pom.xml引入jsp相关开始-->
<dependency>
    <groupid>javax.servlet.jsp</groupid>
    <artifactid>jsp-api</artifactid>
    <version>2.2</version>
</dependency>
<!--引入jsp相关结束-->
<!--web.xml注册-->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.kuang.servlet.Servlet_06_RequestTest</servlet-class>
    </servlet>
    <!--  servlet请求路径-->
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
<!--index.xml登录页面-->


<h2>Hello World! </h2>

<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPast}代表当前的项目--%>

<form action="${pageContext.request.contextPast}/login" method="get">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
</form>



HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;

获取前端传递的参数 并 请求转发

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //后台接收中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("--------------------------------------");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("--------------------------------------");
        
        System.out.println(req.getContextPath());
        //通过请求转发
        //这里的/代表当前Web应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
      
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
    
}
@WebServlet("/req")
public class ReqServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
        System.out.println("url路径:"+req.getRequestURL());
        System.out.println("uri路径:"+req.getRequestURI());
        System.out.println("context路径:"+req.getContextPath());     							req.getRequestDispatcher("/file").forward(req,resp);} 
}
Servlet
<!--web注册-->
<web-app version="4.0" metadata-complete="true" 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_4_0.xsd">

    <servlet>
        <servlet-name>loginServlet</servlet-name>
        <servlet-class>com.kuang.servlet.LoginServlet</servlet-class>
    </servlet>
    <!--  servlet请求路径-->
    <servlet-mapping>
        <servlet-name>loginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    
</web-app>
<!--index.xml登录页面-->

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


    <title>登录</title>



<h1>登录</h1>>

<div style="text-align: center">
        <%--这里表单表示的意思:以post方式提交表单。提交到我们longin请求--%>
        <form action="${pageContext.request.contextPath}/login" method="post">
            用户名:<input type="text" name="password"> <br>
            密码:<input type="password" name="password"> <br>
            爱好:
            <input type="checkbox" name="hobby" value="女孩">女孩
            <input type="checkbox" name="hobby" value="唱歌">唱歌
            <input type="checkbox" name="hobby" value="代码">代码
            <input type="checkbox" name="hobby" value="电影">电影

            <br>
            <input type="submit">
        </form>
</div>



上一篇:设计模式系列7-模版模式


下一篇:(37)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Zuul请求响应信息输出