day40_servlet

文章介绍了Java中的注解机制,包括自定义注解的创建、使用及反射读取注解内容。接着讲解了如何通过注解改造项目,减少web.xml配置。此外,还详细阐述了IDEA中配置热部署的方法,使得代码修改后无需重启服务器。文中讨论了请求转发和重定向的区别,前者是服务器内部操作,地址栏不变,后者涉及两次请求,地址栏会变化,并且请求域数据无法共享。
摘要由CSDN通过智能技术生成

今日内容

零、 复习昨日
一、注解
二、改造项目
三、请求转发
四、重定向

零、 复习昨日

一、注解(Annotation)

注解,又称为注释.它是给程序看的注释.

JDK1.5后才出现的,作用是为了提高开发效率的,如何做到?(一个注解可以简化很多很多代码…)

常见注解: @Override

1.1 自定义注解

1.1.1 新建注解文件

public @interface MyLog {
}

1.1.2 注解加元注解

  • 元注解是给注解加的注解
  • @Target @Retention @Documented @Inherited

@Target

定义自定义注解目标,即注解能作用哪些地方

image-20220902165726025

@Retention

指定注解的保留策略,即注解在什么时期生效.

image-20220902165944320

1.1.3 设置参数

@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
    
    /**
     * 注解的参数,写法是
     * 数据类型 参数名();
     * 参数名设置成value的话,用注解时可以省略
     *      @注解(值)
     * 如果设置成别的名字,使用时参数名不能省略必须是
     *      @注解(参数名1=值)
     * 一旦注解参数超过2个,使用时全部都有加上参数名
     *      @注解(参数名1=值,参数名2=值)
     */
    int value();
    String m2() default "";
    double m3() default 0.0;
}

1.1.4 使用注解

在需要的地方之间加注解即可

1.2 利用反射读取注解内容

模拟UserDao

public class UserDao {


    @MyLog("查询用户")
    @MyAnno
    public void selectOne() {}

    @MyLog("查询全部用户")
    public void selectAll() {}

    @MyLog("删除用户")
    public void deleteOne() {}

}

测试,反射读取注解

public class TestReflact {

    public static void main(String[] args) throws Exception {
        Class<?> userDaoClass = Class.forName("com.qf.annotation.UserDao");
        Method[] methods = userDaoClass.getDeclaredMethods( );

        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            // 获得方法上的注解
            MyLog log = method.getAnnotation(MyLog.class);
            String value = log.value( );

            System.out.println("log = "+value );
            /**
             * 将来可以再获得请求ip,用户名,等信息,配合日志信息插入到数据库
             * 记录到日志表中
             */
        }
    }
}

二、注解改造项目

问题:

​ 每个请求映射,都需要写web.xml的映射

解决:

​ 提供了注解方案

实现:

​ ps: 同一映射,web.xml配置和注解不能共存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1g4CjAjD-1685257229055)(C:/Users/qiush/AppData/Roaming/Typora/typora-user-images/image-20230524111411581.png)]

三、idea配置热部署

换句话就是,可以实现修改代码不重启服务器.

设置idea的Tomcat为这样

image-20230524112659037

image-20221129095612050

设置完之后,修改前端页面,只需要鼠标离开代码,idea就会自动更新前端代码


设置完之后,修改后端代码,只需要点击下面地方,就可以更新服务器中的代码

image-20221129100901138

四、请求转发

3.1 现有问题

  • 响应的代码与接收请求代码在一起
  • 查询全部的代码与登录的代码在一起
  • 这也没有遵循单一职责,不便于后期维护

3.2 解决

  • 将代码拆开
  • 登录请求完之后,再单独设计个Servlet去做查询全部
  • 查询全部之后再单独的做响应
  • 这就是请求转发

3.3 演示

3.3.1 请求转发跳转servlet

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("1 接收请求" );
        System.out.println("2 调用业务层处理数据" );

       // 查询全部
        /**
         * 请求转发,
         * 是服务器内部动作
         */
        // RequestDispatcher rd = req.getRequestDispatcher("/list");
        // rd.forward(req,resp);

        // 一般会简写
        req.getRequestDispatcher("/list").forward(req,resp);

        System.out.println("5 登录结束...." );

    }
}
@WebServlet("/list")
public class ListServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("3查询全部数据..." );

        System.out.println("4 查询全部响应" );
    }
}

3.3.2 请求转发跳转页面

@WebServlet("/page")
public class PageServlet  extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 请求转发是服务器动作,从服务器根路径出发
         * 服务器资源的根路径:/webapp/
         * a.html b.jsp 都定义在/webapp/下
         * c.jsp在 /webapp/WEB-INF/下,所以请求转发时需要加上WEB-INF
         */
        // req.getRequestDispatcher("/a.html").forward(req,resp);
        // req.getRequestDispatcher("/b.jsp").forward(req,resp);
        req.getRequestDispatcher("/WEB-INF/c.jsp").forward(req,resp);
    }
}

image-20230524151019552

3.4 请求域

  • 在两个servlet请求转发时,会存在A类的数据需要传递给B类
  • 此时就需要使用请求对象的请求域功能
  • req.setAttribute(key,value),这样就可以将数据存储在请求对象
  • 再另外一个servlet使用请求对象取出值req.getAttribute(“key”)

image-20220905102349084

image-20220905102434594

3.5 特点

  • 请求转发地址栏不变,这是一次请求
  • 请求转发是服务器内部行为
  • 当做域对象使用,即相当于容器,可以装载数据
  • 两个servlet中请求域数据在一次请求转发中共享

image-20220905105311320

回忆政府办公场景…

五、重定向

重定向也可以使用Servlet直接的跳转,以及跳转页面.

resp.sendRedirect("路径");

演示:

image-20220905112909073

image-20220905112947513

  • 特点
    • 重定向是响应重定向,是浏览器行为
    • 两次请求
    • 地址栏会变化
    • 请求域数据无法共享

image-20220905113940255

六、路径问题

请求转发是服务器行为,服务器根路径是项目名,

​ 所以发请求,从/开始,不会丢失项目名

重定向是浏览器行为,浏览器根路径是端口

​ 所以发请求,从/开始,就会丢项目名

// req.getContextPath(); // 获得项目名 ,例如 /day40
resp.sendRedirect(req.getContextPath()+"/redirect2"); // 拼接项目名


[外链图片转存中…(img-r55gqFJu-1685257229058)]

六、路径问题

请求转发是服务器行为,服务器根路径是项目名,

​ 所以发请求,从/开始,不会丢失项目名

重定向是浏览器行为,浏览器根路径是端口

​ 所以发请求,从/开始,就会丢项目名

// req.getContextPath(); // 获得项目名 ,例如 /day40
resp.sendRedirect(req.getContextPath()+"/redirect2"); // 拼接项目名


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值