• 假期摆烂之学习javaweb


    Mybatis:

    概念:

    是一款优秀的持久层框架,用于简化 JDBC的开发:持久层也就是三层架构里面的dao层,JDBC是规范;框架就是一个半成品的软件,是一套可重复用,通用的,软件基础代码模型;

    JDBC缺点:

    硬编码:

    1.注册驱动,获取链接

    2.SQL语句

    操作繁琐:

    1.手动设置参数

    Mybatis简化:

    将硬编码字符串写到配置文件里,对于操作繁琐的代码自动完成,即免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作

    MyBatis快速入门:

    官网:mybatis – MyBatis 3 | 简介

    1.创建模块,导入坐标;

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0</modelVersion>
    6. <groupId>org.example</groupId>
    7. <artifactId>mybatis-demo</artifactId>
    8. <version>1.0-SNAPSHOT</version>
    9. <properties>
    10. <maven.compiler.source>8</maven.compiler.source>
    11. <maven.compiler.target>8</maven.compiler.target>
    12. </properties>
    13. <dependencies>
    14. <dependency>
    15. <groupId>org.mybatis</groupId>
    16. <artifactId>mybatis</artifactId>
    17. <version>3.5.5</version>
    18. </dependency>
    19. <dependency>
    20. <groupId>mysql</groupId>
    21. <artifactId>mysql-connector-java</artifactId>
    22. <version>5.1.46</version>
    23. </dependency>
    24. <dependency>
    25. <groupId>junit</groupId>
    26. <artifactId>junit</artifactId>
    27. <version>4.13</version>
    28. <scope>test</scope>
    29. </dependency>
    30. <!-- 这里其他的日志以来会自动导入-->
    31. <dependency>
    32. <groupId>ch.qos.logback</groupId>
    33. <artifactId>logback-classic</artifactId>
    34. <version>1.2.3</version>
    35. </dependency>
    36. <dependency>
    37. <groupId>ch.qos.logback</groupId>
    38. <artifactId>logback-access</artifactId>
    39. <version>1.1.7</version>
    40. <exclusions>
    41. <exclusion>
    42. <groupId>ch.qos.logback</groupId>
    43. <artifactId>logback-core</artifactId>
    44. </exclusion>
    45. </exclusions>
    46. </dependency>
    47. </dependencies>
    48. </project>

    2.编写核心配置文件

    1. "1.0" encoding="UTF-8" ?>
    2. configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "https://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <environments default="development">
    7. <environment id="development">
    8. <transactionManager type="JDBC"/>
    9. <dataSource type="POOLED">
    10. <property name="driver" value="com.mysql.jdbc.Driver"/>
    11. <property name="url" value="jdbc:mysql:///chatroomperson?useSSL=false"/>
    12. <property name="username" value="root"/>
    13. <property name="password" value="root"/>
    14. dataSource>
    15. environment>
    16. environments>
    17. <mappers>
    18. <mapper resource="PersonMapper.xml"/>
    19. mappers>
    20. configuration>

    4.编写SQL映射文件

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="test">
    6. <select id="selectAll" resultType="pojo.Person">
    7. select * from person;
    8. select>
    9. mapper>

    5.编码

    {

    定义POJO类

    1. public class Person {
    2. private String account;
    3. private String name;
    4. private String image;
    5. private String signature;
    6. private Date birthday;
    7. private String email;
    8. private String gender;
    9. public String getAccount() {
    10. return account;
    11. }
    12. public void setAccount(String account) {
    13. this.account = account;
    14. }
    15. public String getName() {
    16. return name;
    17. }
    18. public void setName(String name) {
    19. this.name = name;
    20. }
    21. public String getImage() {
    22. return image;
    23. }
    24. public void setImage(String image) {
    25. this.image = image;
    26. }
    27. public String getSignature() {
    28. return signature;
    29. }
    30. public void setSignature(String signature) {
    31. this.signature = signature;
    32. }
    33. public Date getBirthday() {
    34. return birthday;
    35. }
    36. public void setBirthday(Date birthday) {
    37. this.birthday = birthday;
    38. }
    39. public String getEmail() {
    40. return email;
    41. }
    42. public void setEmail(String email) {
    43. this.email = email;
    44. }
    45. public String getGender() {
    46. return gender;
    47. }
    48. public void setGender(String gender) {
    49. this.gender = gender;
    50. }
    51. @Override
    52. public String toString() {
    53. return "Person{" +
    54. "account='" + account + '\'' +
    55. ", name='" + name + '\'' +
    56. ", image='" + image + '\'' +
    57. ", signature='" + signature + '\'' +
    58. ", birthday=" + birthday +
    59. ", email='" + email + '\'' +
    60. ", gender='" + gender + '\'' +
    61. '}';
    62. }
    63. }

    加载核心配置文件获取SqlSessionFactory对象获取该对象执行SQL语句,释放资源

    1. public class MybatisDemo01 {
    2. public static void main(String []args) throws IOException {
    3. //加载mybatis的核心配置文件,获取SqlSessionFactory
    4. //如果在resources目录下面只要写一个名就可以了
    5. String resource = "mybatis-config.xml";
    6. InputStream inputStream = Resources.getResourceAsStream(resource);
    7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    8. //获取SqlSession对象执行sql
    9. SqlSession sqlSession=sqlSessionFactory.openSession();
    10. List<Person>persons=sqlSession.selectList("test.selectAll");
    11. System.out.println(persons);
    12. //释放资源
    13. sqlSession.close();
    14. }
    15. }

    }

    Mapper代理开发:

    目的:

    解决原生方式中的硬编码,简化后期执行SQL

    简化开发:

     1.

     2.

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="mapper.PersonMapper">
    6. <select id="selectAll" resultType="pojo.Person">
    7. select * from person;
    8. select>
    9. mapper>

    3.

    1. //接口类
    2. public interface PersonMapper {
    3. List selectAll();
    4. }

     4.

    1. public class MybatisDemo02 {
    2. public static void main(String []args) throws IOException {
    3. //加载mybatis的核心配置文件,获取SqlSessionFactory
    4. //如果在resources目录下面只要写一个名就可以了
    5. String resource = "mybatis-config.xml";
    6. InputStream inputStream = Resources.getResourceAsStream(resource);
    7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    8. //获取SqlSession对象执行sql
    9. SqlSession sqlSession=sqlSessionFactory.openSession();
    10. //获取UserMapper接口的代理对象
    11. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    12. List<Person>persons=personMapper.selectAll();
    13. System.out.println(persons);
    14. //释放资源
    15. sqlSession.close();
    16. }
    17. }

     细节:

    1. <mappers>
    2. <package name="mapper"/>
    3. mappers>

    Mybatis核心配置文件: 

    enviroments:配置数据库连接环境信息,可以配置多个environment,通过default属性切换不同的environment

    typeAlias:别名可以简化配置:

    1. <typeAliases>
    2. <package name=""/>
    3. </typeAliases>

    引号里面写要连接的接口的包,然后就可以在对应的接口包里面不要写这个包了例如:

    1. <typeAliases>
    2. <package name="pojo"/>
    3. </typeAliases>

    然后在对应的 PersonMapper的xml文件里面可以做这样的改变:

    1. <select id="selectAll" resultType="pojo.Person">
    2. select * from person;
    3. </select>

    变成 

    1. <select id="selectAll" resultType="Person">
    2. select * from person;
    3. </select>

    注意:配置各个标签时,需要遵守前后顺序 ;

    配置文件增删改查和动态SQL:

    MybatisX插件是一款基于IDEA快速开发插件,为效率而生

    具体步骤如下:

    06-MyBatis案例-环境准备_哔哩哔哩_bilibili

    查询: 

    步骤:

    1.编写接口方法;

    2.编写SQL语句;SQL映射文件;

    3.执行方法测试;

    注意:如果表的类里面有和表里面的字段不一样的,那么就不会自动封装,这时候就可以将查询的字段起别名使得别名和该类属性一样;但是这样的话如果有多个片段就要多次操作,所以可以通过导入一个sql片段。变成这样:

    但是还有更灵活的方法:

     

    1. <!--namespace:名称空间-->
    2. <mapper namespace="mapper.PersonMapper">
    3. <resultMap id="personResultMap" type="pojo.Person">
    4. <result column="name" property="nameCopy"/>
    5. </resultMap>
    6. <select id="selectAll" resultMap="personResultMap">
    7. select * from person;
    8. </select>
    9. </mapper>
    查看详情:

    get小知识:接口里面默认方法都是public

     mybatis里面有两种参数占位符的不同书写格式:

    1. 1.#{}替换为?,为了防止SQL注入
    2. 2.${}拼接sql语句,会存在sql注入问题
    3. 3.使用时机:
    4. 参数传递用#{}
    5. 表名或列名不固定的情况下${}会存在SQL语句注入的问题
    6. 特殊字符处理:
    7. 1.转义字符:&lt 小于号
    8. 2.CDATA区
    9. -----------------------------------------------------------
    10. </select>
    11. <select id="selectAccount" resultMap="personResultMap">
    12. select * from person where account=#{account};
    13. </select>
    14. 参数类型parameterType可以省略

    条件查询: 

    参数接收三种方式:

    1. <select id="selectByCondition" resultMap="personResultMap">
    2. select *
    3. from person
    4. where gender=#{gender}
    5. and name like #{nameCopy}
    6. <!-- 注意这里一定后面的要对应对象的属性名-->
    7. </select>
    8. ------------------------------------------------------------------------
    9. public void selectByCondition() throws IOException {
    10. //接收参数
    11. String gender="女";
    12. String nameCopy="小麻子";
    13. //处理参数
    14. nameCopy=nameCopy+"%";
    15. Map map=new HashMap();
    16. map.put("gender",gender);
    17. map.put("nameCopy",nameCopy);
    18. String resource = "mybatis-config.xml";
    19. InputStream inputStream = Resources.getResourceAsStream(resource);
    20. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    21. //2.获取SqlSession对象
    22. SqlSession sqlSession=sqlSessionFactory.openSession();
    23. //3。获取Mpper接口的代理对象
    24. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    25. //4.执行方法
    26. //List<Person>persons=personMapper.selectByCondition(gender,nameCopy);
    27. // List<Person>persons=personMapper.selectByCondition(person);
    28. List<Person>persons=personMapper.selectByCondition(map);
    29. System.out.println(persons);
    30. //5.释放对应的资源
    31. sqlSession.close();
    32. }

     注意:这个#号里面的属性要对应对象类里面的属性;

    添加:

    步骤:

    1.编写接口方法:Mapper接口

    void add(Person person);

    2.编写SQL语句:SQL映射文件

    1. <insert id="add">
    2. insert into person(name,account,gender)
    3. values(#{nameCopy},#{account},#{gender})
    4. </insert>

    3.执行方法,测试

    1. @Test
    2. public void add() throws IOException {
    3. //接收参数
    4. String gender="女";
    5. String nameCopy="小麻子";
    6. //处理参数
    7. nameCopy=nameCopy+"%";
    8. Person p=new Person();
    9. p.setGender(gender);
    10. p.setNameCopy(nameCopy);
    11. p.setAccount("1111111111");
    12. String resource = "mybatis-config.xml";
    13. InputStream inputStream = Resources.getResourceAsStream(resource);
    14. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    15. //2.获取SqlSession对象
    16. SqlSession sqlSession=sqlSessionFactory.openSession();
    17. //3。获取Mpper接口的代理对象
    18. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    19. //4.执行方法
    20. //List<Person>persons=personMapper.selectByCondition(gender,nameCopy);
    21. // List<Person>persons=personMapper.selectByCondition(person);
    22. personMapper.add(p);
    23. //提交事务
    24. sqlSession.commit();
    25. //5.释放对应的资源
    26. sqlSession.close();
    27. }

    本来代码交了之后会发现没有报错,运行成功,但是没有出现新的记录在数据库里面,这是由于mybatis默认事务提交是false,这样的话执行之后没有提交就会回滚;解决方法:(上面代码采用了第一种解决方式)

    1.在释放资源之前手动提交事务;

    2.在openSession的时候写入参数true;

    附上:主键返回:

     对于添加的信息里面没有包括主键,但是后面还要返回主键这种情况下,可以用这个:

    1. <insert id="add" useGeneratedKeys="true" keyProperty="account">
    2. insert into person(name,account,gender)
    3. values(#{nameCopy},#{account},#{gender})
    4. </insert>

     这样可以做到在调用完add方法之后就可以得到主键值了,这里的account是我自己输入的,并且我这个是可以直接返回的,这只是做测试用例;

    修改:

    int update(Person person);
    1. <update id="update">
    2. update person
    3. set name=#{nameCopy},
    4. gender=#{gender}
    5. where account=#{account};
    6. </update>
    1. @Test
    2. public void update() throws IOException {
    3. //接收参数
    4. String gender="女";
    5. String nameCopy="小麻子+++";
    6. //处理参数
    7. nameCopy=nameCopy+"%";
    8. Person p=new Person();
    9. p.setGender(gender);
    10. p.setNameCopy(nameCopy);
    11. p.setAccount("1111111111");
    12. String resource = "mybatis-config.xml";
    13. InputStream inputStream = Resources.getResourceAsStream(resource);
    14. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    15. //2.获取SqlSession对象
    16. SqlSession sqlSession=sqlSessionFactory.openSession();
    17. //3。获取Mpper接口的代理对象
    18. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    19. //4.执行方法
    20. //List<Person>persons=personMapper.selectByCondition(gender,nameCopy);
    21. // List<Person>persons=personMapper.selectByCondition(person);
    22. System.out.println(personMapper.update(p));
    23. //提交事务
    24. sqlSession.commit();
    25. //5.释放对应的资源
    26. sqlSession.close();
    27. }
    删除:

    删除一个:

    void deleteByAccount(Person person);
    1. <delete id="deleteByAccount">
    2. delete from person where account=#{account};
    3. </delete>

    1. @Test
    2. public void deleteByAccount() throws IOException {
    3. //接收参数
    4. //处理参数
    5. Person p=new Person();
    6. p.setAccount("1111111111");
    7. String resource = "mybatis-config.xml";
    8. InputStream inputStream = Resources.getResourceAsStream(resource);
    9. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    10. //2.获取SqlSession对象
    11. SqlSession sqlSession=sqlSessionFactory.openSession();
    12. //3。获取Mpper接口的代理对象
    13. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    14. //4.执行方法
    15. //List<Person>persons=personMapper.selectByCondition(gender,nameCopy);
    16. // List<Person>persons=personMapper.selectByCondition(person);
    17. personMapper.deleteByAccount(p);
    18. //提交事务
    19. sqlSession.commit();
    20. //5.释放对应的资源
    21. sqlSession.close();
    22. }

    动态SQL:

    多条件动态条件查询:

    标签:可以用if标签将会变换的SQL语句放到里面去,但是会造成一个问题,可能and语句赘余,为了解决这个,新推出一个where标签:

    1. </select>
    2. <select id="selectByCondition" resultMap="personResultMap">
    3. select *
    4. from person
    5. <where>
    6. <!-- 几点要注意:首先if里面的属性要和类对象对应,而且字符串类型要注意判断空字符串,并且用!=和不带空格的单引号-->
    7. <if test="gender!=null and gender!=''">
    8. gender=#{gender}
    9. </if>
    10. <if test="nameCopy!=null and nameCopy!=''">
    11. and name like #{nameCopy}
    12. </if>
    13. </where>
    14. <!-- 注意这里一定后面的要对应对象的属性名-->
    15. </select>
     单条件的动态条件查询:

    choose(when,otherwise)

    1. </select>
    2. <select id="selectByConditionSingle" resultMap="personResultMap">
    3. select *
    4. from person
    5. where
    6. <choose><!--相当于switch-->
    7. <when test="gender!=null and gender!=''">
    8. gender=#{gender}
    9. </when>
    10. <when test="nameCopy!=null and nameCopy!=''">
    11. name like #{nameCopy}
    12. </when>
    13. </choose>
    14. </select>

    但是在这种情况下,当什么都没有的时候时会报错的,这时候的格式问题还是可以用where来处理;

    修改动态字段:

    修改字段和普通修改字段类似,也是用if标签,但是对于格式和规范化问题,这里用的不是where而是update;

    批量删除: 

    批量删除参数要变成主键(一般来说)的数组

     void deleteByAccounts(@Param("accounts") String []accounts);
    1. <delete id="deleteByAccount">
    2. delete from person where account=#{account};
    3. </delete>
    4. <delete id="deleteByAccounts">
    5. delete from person where account in(
    6. <foreach collection="accounts" item="account" separator=",">
    7. #{account}
    8. </foreach>
    9. )
    10. </delete>

    1. @Test
    2. public void deleteByAccounts() throws IOException {
    3. //接收参数
    4. String []accounts={"0866170880","1106231296"};
    5. //处理参数
    6. Person p=new Person();
    7. p.setAccount("1111111111");
    8. String resource = "mybatis-config.xml";
    9. InputStream inputStream = Resources.getResourceAsStream(resource);
    10. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    11. //2.获取SqlSession对象
    12. SqlSession sqlSession=sqlSessionFactory.openSession();
    13. //3。获取Mpper接口的代理对象
    14. PersonMapper personMapper=sqlSession.getMapper(PersonMapper.class);
    15. //4.执行方法
    16. //List<Person>persons=personMapper.selectByCondition(gender,nameCopy);
    17. // List<Person>persons=personMapper.selectByCondition(person);
    18. personMapper.deleteByAccounts(accounts);
    19. //提交事务
    20. sqlSession.commit();
    21. //5.释放对应的资源
    22. sqlSession.close();
    23. }

    注意:这里由于有写可以简化的:比如在上面的xml的文件里面可以将两个括号去掉改成这样效果是一样的:

    1. </delete>
    2. <delete id="deleteByAccounts">
    3. delete from person where account in
    4. <foreach collection="accounts" item="account" separator="," open="(" close=")">
    5. #{account}
    6. </foreach>
    7. </delete>

    如果之前的接口代码里面没有用注解改的话,一般时array数组,比如做这样的修改:

    void deleteByAccounts(String []accounts);
    1. </delete>
    2. <delete id="deleteByAccounts">
    3. delete from person where account in
    4. <foreach collection="array" item="account" separator="," open="(" close=")">
    5. #{account}
    6. </foreach>
    7. </delete>

     

    注解完成增删改查:

    即将配置文件里面的SQL语句直接在接口类里面用注解完成:

    1. @Select("select * from person")
    2. List selectAll();

    但是这样会导致在配置文件处理的东西就会失效,所以说注解适合处理比较简单的SQL语句; 

    过滤器:

    概念:

    把对资源的请求拦截下来

    过滤器的快速入门:

     1.定义类,实现Filter接口,并重写其所有方法

    1. package webtest.filter;
    2. import javax.servlet.*;
    3. import javax.servlet.annotation.WebFilter;
    4. import java.io.IOException;
    5. @WebFilter("/*")
    6. public class FilterDemo implements Filter {
    7. @Override
    8. public void init(FilterConfig filterConfig) throws ServletException {
    9. }
    10. @Override
    11. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    12. System.out.println("filterDemo...");
    13. filterChain.doFilter(servletRequest,servletResponse);
    14. }
    15. @Override
    16. public void destroy() {
    17. }
    18. }

    2.配置拦截资源的路径,在类定义上@WebFilter注解,这里一定要注意是@WebFilter注解,别搞错了,不然会一直拦截不了;

    3.在doFilter方法中输出一句话,并放行        

    执行流程:

    对于web资源和浏览器的交互,中间如果有一个过滤器的话,有这样的执行流程:

    先是服务器向web资源请求数据,然后经过过滤器处理,也就是执行过滤器doFilter方法前面的代码,然后访问资源里面的数据,之后再执行过滤器后面的代码;

    Filter拦截路径的配置:

    过滤器链:

    如果有多个过滤器,对于过滤器的执行顺序,按照类名的字符串的自然排序来进行的;

    执行顺序和这样的顺序一样:

    Listener:

     练习:

    1.定义类,实现ServletContextListener接口

    2.在类上添加@WebListener注解

    1. @WebListener
    2. public class LoaderListener implements ServletContextListener {
    3. @Override
    4. public void contextInitialized(ServletContextEvent servletContextEvent) {
    5. System.out.println("初始化。。。");
    6. }
    7. @Override
    8. public void contextDestroyed(ServletContextEvent servletContextEvent) {
    9. }
    10. }

    RBAC模型:

    一种权限控制的数据库表设计(...)

    05_RBAC_菜单管理案例_需求介绍_数据库设计_尚学堂_哔哩哔哩_bilibili

    会话跟踪技术:

    概念:

    一种维护浏览器状态的方法,服务器需要识别多次请求是否来自同一浏览器,以便在同一次会话的多次请求中共享数据(HTTP是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享)

    实现方式:

    客户端会话跟踪技术:Cookie

    服务端会话跟踪技术:Session

    Cookie:

    Cookie基本使用:

    发送:

    获取:

    Cookie原理:

     Cookie存活时间:

    默认情况下,存活时间在浏览器内存中,当浏览器关闭,内存释放则销毁

    Cookie存储中文:

    Cookie不能直接存储中文:

    如需储存,则进行URL编码的转码;

    Session:

    Session基本使用:

    1. HttpSession session= req.getSession();
    2. session.setAttribute("username","zs");
    1. HttpSession session=req.getSession();
    2. Object username=session.getAttribute("username");
    3. System.out.println(username);
    Session原理:

     Session是基于Cookie实现的

     Session钝化、活化:

    钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中

    活化:再次启动服务器后,从文件加载数据到Session中;

    Session销毁:

    默认情况下,无操作,30分钟自动销毁,但是可以配置:

    调用Session对象的invalidate方法也可以销毁;

    Cookie和Session的区别:

    储存位置:Cookie是将数据存储在客户端,Session将数据存储在服务器端;

    安全性:Cookie不安全,Session安全

    数据大小:Cookie最大3KB,Session无大小限制

    存储时间:Cookie可以长期储存,Session默认三十分钟

    服务器性能:Cookie不占服务器资源,Session占用服务器资源

    Response和Request:

    基本认识:

    request获取请求对象:

    response设置请求对象:

    request继承体系:

    tomcat创建request对象 ,创建实现类;

    request获取请求数据:

     请求头:

    请求体:

     

     request用通用方式获取请求参数:

     示例代码:

    1. Map<String,String[]>map= req.getParameterMap();
    2. for(String key:map.keySet())
    3. {
    4. System.out.println(key+":");
    5. //获取值
    6. String[]values=map.get(key);
    7. for (String value:values)
    8. {
    9. System.out.println(value+"");
    10. }
    11. }
    12. System.out.println("------------------------------------------------------------");
    13. //根据key获取参数值数组,
    14. String[] hobbies=req.getParameterValues("hobby");
    15. for(String hobby:hobbies)
    16. {
    17. System.out.println(hobby);
    18. }
    19. //根据key获取参数值:
    20. String username=req.getParameter("username");
    21. System.out.println(username);
    22. }

     请求方式解决中文乱码问题:

    post解决方式:

    get解决方式:

    乱码原因:

    解决方法:虽然两个程序的编解码方式不同,但是底层的字节数组是一样的,可以将后面的带的乱码的数据按相应的规则解码成相应的字节数组,然后再转换成汉字字符串;

    1. String username=req.getParameter("username");
    2. System.out.println(username);
    3. //编码成字节数组
    4. byte[]bytes=username.getBytes(StandardCharsets.ISO_8859_1);
    5. //解码成字符串
    6. username=new String(bytes,StandardCharsets.UTF_8);
    7. System.out.println(username);

    request请求转发: 

     请求转发的特点:

    浏览器地址栏路径不发生变化;

    只能转发到当前服务器的内部资源;

    一次请求,可以在转发的资源间使用request共享数据

    Response设置响应数据方法:

    Response重定向:

    一种资源跳转方式,

    1. //重定向
    2. //方法一:
    3. //设置响应状态码 302
    4. //resp.setStatus(302);
    5. //设值响应头
    6. //注意:这里路径要加上虚拟目录,默认虚拟目录是项目名
    7. //resp.setHeader("location","/web-demo/demo02");
    8. //方法二:
    9. resp.sendRedirect("/web-demo/demo02");

    重定向特点: 

    浏览器地址栏路径发生变化

    可以重定向道任意位置的资源(服务器内部,外部均可)

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

    资源路径问题:

    浏览器使用:需要加虚拟目录(项目访问路径)

    服务端使用:不需要加虚拟目录

    虚拟目录可以动态配置:

    所以可以动态获取虚拟目录:getContextPath方法

     Response响应数据:

    响应字符数据:

    1. resp.setContentType("text/html;charset=utf-8");
    2. //1.获取字符输出流
    3. PrintWriter writer= resp.getWriter();
    4. writer.write("你好");
    5. writer.write("

      你好

      "
      );

    响应字节数据:

    1. //读取文件
    2. FileInputStream fileInputStream=new FileInputStream("D://a.jpg");
    3. // 获取response字节输出流
    4. ServletOutputStream os=resp.getOutputStream();
    5. //完成流的copy
    6. // byte[]buff=new byte[1024];
    7. // int len=0;
    8. // while((len=fileInputStream.read(buff))!=-1)
    9. // {
    10. // os.write(buff,0,len);
    11. // }
    12. //
    13. // fileInputStream.close();
    14. IOUtils.copy(fileInputStream,os);

    idea模板创建servlet:

     点击Settings,Editor中的File and Code Templates,选择Other选框:Web里面Java Code Templates里面的Servlet Annotated Class;

    MVC模式和三层架构

    mvc: 

    分层开发的模式
    好处:

    职责单一,互不影响;

    有利于分工协作:

    有利于组件重用:

    三层架构:

     

      mvc和三层架构关系:

    假期结束了,又要好好学习了。。。、

    任何事情在尘埃落定之前都是未知的 付出不一定跟收获成正比 但尽全力去做是绝对不会错的 哪怕做不好也没关系 就是不要在开始之前就说我不行 这很重要。

  • 相关阅读:
    pnpm:简介
    MOV导出序列帧并在Unity中播放
    数据分析Pandas专栏---第四章<Pandas几个处理元素的函数>
    微服务负载均衡器LoadBalancer实战
    微信小程序:炫酷恶趣制作神器小程序源码
    Linux权限基础知识
    切面aspect处理fegin调用转本地调用
    DPDK EAL
    驱动开发:内核特征码搜索函数封装
    数据库系统原理与应用教程(071)—— MySQL 练习题:操作题 110-120(十五):综合练习
  • 原文地址:https://blog.csdn.net/weixin_74789176/article/details/132546209