• java web dev知识积累


    tomcat体系结构

    可以从tomcat的server.xml文件中元素的层次结构来理解tomcat的体系结构:

    Server(可以视为tomcat本身)->经由connector可以有多个(coyote默认为Bio阻塞式io)处理socket分发->Service可以有多个(Catalina Container容器)(一般由catalina container来调用用户的web app java代码)->一个engine->多个host虚拟主机->多个context(就是web app)

    每个由host定义的虚拟主机中可以定义多个context(也就是web app或者说modules)

    war打包部署:

    jar cvf myapp.war webproject-directory

    该命令将创建myapp.war部署文件。

    需要注意的是该文件对于tomcat来说也是一个文件夹。只要访问url到了/myapp,tomcat就会首先将myapp.war解压,并且根据该war中的web.xml配置来寻址url对应的class并且执行后返回结果

    maven

    maven是一个apache基金会开源的java构建,依赖管理的工具,类似C语言下的make,本身也是java写的

    maven的特点:

    1. 约定优先,maven非常强烈地建议相应最佳实践下的目录结构

    2. 内置提供了第三方依赖管理,支持自建自管仓库,项目的依赖直接从这个仓库中下载

    3. 提供了一致的构建过程

    4. 插件式架构,大量的可用插件完成我们的构建流程

    5. 方便和IDE集成

    maven安装使用过程:

    1. 下载http://mirror.bit.edu.cn/apache/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.zip

    2. 解压,并且将对应bin目录放到path环境变量中,配置环境变量M2_HOME=/path/to/maven

    3. mvn -v确保正常输出

    由于国内访问maven仓库非常慢,阿里云公益心做了对应的镜像。

    <mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>

    maven的pom.xml(project object model)文件

    项目坐标:

    groupId,组织,比如com.example

    artifactId,项目标识符,比如mymodule,myproject等;

    version, 版本,比如1.0.1-SNAPSHOT,这里snapshot在maven构建时将被替换为timestamp

    dependencies

    这里描述本项目的依赖

    <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>

    classpath

    classpath用于连接java run time library和文件系统。它定义编译器和解释器应该在何处去查找要加载的.class文件。其基本思想是:文件系统的层次结构就反映了java包的层次结构,而classpath则定义了文件系统中的哪些目录可以作为java包层次结构的根(root)

    https://www.ibm.com/developerworks/cn/java/j-classpath-windows/

    请求转发forward和重定向redirect

    请求转发是由servlet将当前的request和response交给另外的组件处理,最终由其他组件负责返回浏览器响应。对于浏览器来说,这是一次请求,一次响应。请求的转发发生在服务端内部。浏览器地址栏并不会改变;

    RequestDispatcher(forward或者include(include是所有组件都可以输出信息))的获取

    通过HttpServletRequest获取,通过ServletContext获取

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            RequestDispatcher rd = req.getRequestDispatcher("/forwardExample");
            rd = this.getServletContext().getNamedDispatcher(
                    "ServletForwardExample");
            rd = this.getServletContext().getRequestDispatcher("/forwardExample");
            rd.forward(req, resp);
        }

    sendRedirect

    通过response对象发送给浏览器一个新的url地址,往往就是http location,浏览器自动跳转

    监听器

    监听器分类

    按照监听器所监听的对象可以分为:

    监听应用程序环境(ServletContext),又可以细致分为ServletContextListener(创建和销毁),ServletContextAttributeListener(对象属性的CRUD),

    监听用户请求对象(ServletRequest),也可以细致分为:ServletRequestListener(创建和销毁),ServletRequestAttributeListener(对象属性的CRUD)

    监听用户会话对象(HttpSession),也可以细致分为HttpSessionListener(创建和销毁),HttpSessionAttributeListener(对象属性的CRUD),HttpSessionActivationListener监听session持久化到磁盘,或者从磁盘恢复到内存的事件。

    HttpSessionBindingListener: attribute方法调用或者removeAttribute方法调用时会触发

    监听器,过滤器,Servlet的启动顺序

    监听器,过滤器或者Servlet的启动顺序首先取决于在部署描述符web.xml中定义的顺序,按照其定义顺序而顺序创建的。

    监听器优先级,高于过滤器,高于Servlet

    servlet并发

    servlet并发线程模型:

    多个请求访问同一个servlet时,由于被容器分别以多个worker线程来调用单实例servlet对应的service方法,因此在servlet的开发中,我们必须注意线程安全问题!!

    servlet并发处理的特点:

    1. 单实例,我们知道servlet的生命周期中只初始化创建一次,也就是单实例

    2. 多线程,当多个用户同时访问同一个servlet时,对应的servlet的service方法或者get,post方法将在不同的worker thread中同时执行,也就是具有多线程运行模式;

    3.线程不安全,也正是因为1,2两个特点导致了servlet是线程不安全的。

    如何做到servlet线程安全?

    变量的线程安全:

    1. 参数变量本地化,由于local变量并不暴露在不同的线程中,因此是线程安全的;

    2. 对于需要同步访问的线程不安全变量写访问时,必须加上synchronized锁

    属性的线程安全:

    1. ServletContext的属性是线程不安全的

    2. HttpSession理论上是线程安全的,但是如果同一个用户在浏览器同一个进程中打开多个tab也可能不安全;

    3.ServletRequest是线程安全的,因为它是在每一次request时创建并供使用的数据

    以下两点需要注意:

    1. 避免在Servlet中再创建新的线程,这将会导致程序异常复杂,容易出错;

    2. 多个Servlet需要访问同一个外部对象时,必须加锁处理

    public class ConcurrentServlet extends HttpServlet {
    
        String name; // 尽量避免使用这类实例变量,因为这是线程不安全的,如果必须使用则必须加锁
    
        /**
         * 
         */
        private static final long serialVersionUID = -6948878379930865229L;
    
        @Override
        public void init() throws ServletException {
            super.init();
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            synchronized (this) {
                name = req.getParameter("username");
                PrintWriter out = resp.getWriter();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                out.println("username: " + name);
            }
        }
    
        @Override
        public void destroy() {
            super.destroy();
        }
    }

  • 相关阅读:
    编程算法
    2048小游戏主要算法实现
    Spring 计时器 @Scheduled cron 含义
    jQuery Validate Ajax 验证
    jQuery Validate 使用
    Java 两个整数相除保留两位小数,将小数转化为百分数
    mybatis+mysql返回插入的主键,参数只是提供部分参数
    微信 创建自定义菜单 向微信发起的post请求
    JSON.parse()和JSON.stringify()
    前台JSON字符串,spring mvc controller也接收字符串
  • 原文地址:https://www.cnblogs.com/kidsitcn/p/10298264.html
Copyright © 2020-2023  润新知