Servlet

Servlet

Maven添加依赖项

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>4.0.1</version>
  <scope>provided</scope>
</dependency>

实现Servlet方法

package anti.o2;

import javax.servlet.*;
import java.io.IOException;

public class Demo implements Servlet {
    /**
     * @param servletConfig
     * @throws ServletException
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        
    }

    /**
     * @return
     */
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    /**
     * @return
     */
    public String getServletInfo() {
        return null;
    }

    /**
     *
     */
    public void destroy() {

    }
}
  • 实现Servlet接口
  • image
  • 然后在注解中配置访问路径
  • service方法每次请求被调用

HttpServelet

  • 继承HttpServlet类,实现doGet和doPost方法的封装

  • 继承后需要重写doXxx类

  • <form action="/WebApp/Demo2" method="post">
        <input name="username">
        <input type="submit" >
    </form>
    
    
    实现将表单提交到Demo2的doPost类处理
    

Servlet urlPattern

  • 一个Servlet可以配置多个urlPattern

    • 例如

    • @WebServlet(urlPatterns = {"/Demo2","/Demo3"})
      
  • 配置规则

    • 精确匹配
      • 配置路径和访问路径要求完全一致
    • 目录匹配
      • 例如@WebServlet(urlPatterns ="/demo/*")
      • 优先匹配精确匹配
    • 扩展名匹配
      • 例如@WebServlet(urlPatterns ="*.do")
      • 不能在前面加斜杠
    • 任意匹配
      • @WebServlet(urlPatterns ="/")
      • @WebServlet(urlPatterns ="/*")
      • 这样任意路径都可以访问
      • 会覆盖掉原来的静态资源访问
  • XML配置Servlet

    • 在Web.xml中配置Servlet

    • 这种方法较老,不推荐

    • <servlet>
        <servlet-name>examppppple</servlet-name>
        <servlet-class>anti.o2.Demo3</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>examppppple</servlet-name>
        <url-pattern>/demo3</url-pattern>
      </servlet-mapping>
      

Request和Response对象

Request

  • ServletRequest

  • HttpServletRequest继承

  • RequestFacade :Tomcat定义的实现类,生成Request对象

  • Request获取请求数据

    • 请求数据分为3部分

    • String getMethod()获取请求方式:GET

    • String getContextPath() 获取项目路径

    • StringBuffer getRequestURL() 获取URL

    • String getRequestURI() 获取URI (后面的路径)

    • String getQueryString();

    • 运行以下代码

    • protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          System.out.println("get...");
          String method = req.getMethod();
          System.out.println(method);
      
          String contextpath = req.getContextPath();
          System.out.println(contextpath);
          String URL = String.valueOf(req.getRequestURL());
          System.out.println(URL);
          String URI = req.getRequestURI();
          System.out.println(URI );
      }
      
    • 获得结果image

请求头
  • String getHeader(String name)
  • 获取值
请求体
  • ServletInputStream getInputStream();GET获取字节输入流

  • BufferedReader getReader()POST获取字符输入流

  • 通过流获取请求体信息

  • BufferedReader br = req.getReader();
    System.out.println(br.readLine());
    
请求方法
  • Map<String,String[]> getParameterMap()获取所有参数集合
  • 这个是get和post通用的,底层通过getReader和getInputStream对请求体解析实现

Response

  • 相应数据分为3部分
响应行
  • HTTP/1.1 200 OK
  • void setStstus(int sc)设置相应状态码
响应头
  • 例如Context-Type:text/html

  • 设置返回为html代码如下

  • resp.setHeader("context-type","text/html");
    
  • void setHeader(String name, String value)

  • resp.setContentType("text/html;charset=utf-8");
    
    设置编码方式,防止中文乱码
    
响应体
  • PrintWriter getWriter()获取字符输出流
  • ServletOutputStream getOutputStream()获取字节输出流
读取文件
FileInputStream fis =new FileInputStream("location");

    ServletOutputStream outputStream = resp.getOutputStream();

        byte[] buff = new byte[1024];
        int len = 0;
        while((len = fis.read(buff))!=-1){
            outputStream.write(buff,0,len);
        }
        fis.close();
  • 也可以使用封装方法

    • 首先导入IOUtils工具类

    • <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
      </dependency>
      
    • 然后使用copy方法直接复制

    • FileInputStream fis =new FileInputStream("C:\\Users\\Anti\\Pictures\\R6.png");
      
      ServletOutputStream outputStream = resp.getOutputStream();
      
      IOUtils.copy(fis,outputStream);
      fis.close();
      
重定向
resp.setStatus(302);
resp.setHeader("location","B的路径")

或者使用封装方法

resp.sendRedirect("location");

  • 重定向会使浏览器url发生变化

  • 可以重定向到任意资源

  • 两次请求,不能在多个资源中使用request共享数据

  • 可以通过.getContextPath获取路径

  •  String context = req.getContextPath();
    resp.sendRedirect(context+ "/resp2");
    

乱码问题处理

  • Post: getReader()

    • request.setCharacterEncoding("UTF-8")解决字符乱码
  • get:String getQueryString()获取参数

    • 浏览器用UTF-8给URL编码。

      • URL将编码方式转化为二进制。一个汉字->三字节->24位
      • 每个字节转化为2个16进制数并在前面加上%image
    • TomCat用ISO-8859-1解码,故产生乱码

    • public class Test {
          public static void main(String[] args) throws UnsupportedEncodingException {
                  String user = "氧";
                  String encode = URLEncoder.encode(user,"utf-8");
                  System.out.println(encode);
                  System.out.println(URLDecoder.decode(encode,"utf-8"));
          }
      }
      
  • 输出

%E6%B0%A7
氧
  • get乱码解决思路:

    • 将乱码解码为字节数组

    • String username =req.getParameter("username");
      System.out.println("处理前"+username);
      byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
      String user =  new String(bytes,"utf-8");
      System.out.println("处理后"+user);
      
    • image

资源转发

  • 将请求和相应给另一个类处理
  • image例如定义两个类
  • req.getRequestDispatcher("/F2").forward(req,resp);实现转发。Dispatcher是调度员的意思
  • image这是F1
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tV6xC6Zp-1664949121008)(C:\Users\Anti\AppData\Roaming\Typora\typora-user-images\image-20221004230937830.png)]这是F2
  • imageGet请求F1的效果
  • image但是上方的URL并没有改变
  • 使用Request对象方法
    • setAttribute(String,Object)存储数据到request域中
    • Object getAttribute(String name)跟据key获得值
    • void removeAttribute(String name)删除值

Servlet+MyBatis实现密码登陆

添加依赖项

  • 先添加Maven。注意检查Mysql版本!!!
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
  </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
</dependencies>
  • 添加mybatis-config

  • <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--起别名-->
        <typeAliases>
            <package name="anti.o2.pojo"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/db1"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--扫描mapper-->
            <package name="anti.o2.mapper"/>
        </mappers>
    </configuration>
    
  • 放在resources里面

创建映射

  • 创建mapper包

  • mapper下创建UserMapper接口

  • resources下创建UserMapper.xml配置文件

  • image

  • <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="anti.o2.mapper.UserMapper">
    
    </mapper>
    

HTML文件

<div id="loginDiv">
    <form action="/WebApp/login" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
        <p>Username:<input id="username" name="username" type="text"></p>

        <p>Password:<input id="password" name="password" type="password"></p>

        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">没有账号?点击注册</a>
        </div>
    </form>
</div>

注册实现

  • 通过检查用户名判断是否重复

  • 添加用户

  • <insert id="insertUser">
        insert into tb_user(username,password)
        values(#{username},#{password})
    </insert>
    <select id="select" resultType="anti.o2.pojo.User">
        select * from tb_user
        where
        username = #{user}
        and
        password = #{pass}
    </select>
    <select id="selectByUserName" resultType="anti.o2.pojo.User">
        select * from tb_user
        where
        username = #{username}
    </select>
    
  • User selectByUserName(@Param("username")String username);
    
    void insertUser(@Param("username")String username,@Param("password")String password);
    
  • @WebServlet("/registerServlet")
    public class Register extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
    
            //调用方法
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
            User user1 = mapper.selectByUserName(username);
            if(user1!=null)
            {
                resp.setContentType("text/html;charset=utf-8");
                resp.getWriter().write("用户已存在 Existed");
            }
            else
            {
                mapper.insertUser(user);
                sqlSession.commit();
                resp.getWriter().write("用户注册成功 Success");
            }
            sqlSession.close();
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doGet(req,resp);
        }
    }
    

代码优化

  • SqlSessionFactory不应该被创建多次,否则创建了多个连接池

  • 创建工具类,获得一个固定的SqlSessionFactory

  • public class SqlSession {
    
        private static SqlSessionFactory sqlSessionFactory;
        static {
            //静态代码块随着类的加载自动执行,且只会执行一次
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }
        public static SqlSessionFactory getSqlSessionFactory(){
            return sqlSessionFactory;
        }
    }
    
  • 然后在代码中修改image这样就能使用固定的连接池了

  • sqlsession不能够被重复使用,否则会相互影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值