JavaWeb开发快速上手篇

参考链接:

距上一次接触JavaWeb已经快6年时间了,最近因工作原因需要学习Web开发知识,这里做一个简单的记录。所以本文适合对JavaWeb开发有一定了解和基础的人群,达到快速拾起并上手的目的。

开发工具:IntelliJ IDEA 构建工具:Maven

创建工程

File -> New -> Project -> Java -> Java Web

创建JavaWeb工程

工程目录结构:

TestWeb
│  TestWeb.iml
│
├─.idea
│  │  encodings.xml
│  │  misc.xml
│  │  modules.xml
│  │  workspace.xml
│  │
│  └─artifacts
│          TestWeb_war_exploded.xml
│
├─out
│  └─artifacts
│      └─TestWeb_war_exploded
│          │  index.jsp
│          │
│          └─WEB-INF
│                  web.xml
│
├─src
└─web
    │  index.jsp
    │
    └─WEB-INF
        │  web.xml
        │
        ├─classes
        └─lib

配置copile Path (将WEB-INFO/classes目录配置进来)

配置copilePath

配置 Denpendencies (将WEB-INF/lib目录配置进来)

配置Denpendencies

选择lib目录后下一步选择Jar Directory

配置tomcat

配置Configurations

菜单栏 run -> Edit Configurations 或 右上角有个向下的小箭头

新建Tomcat Server

提醒:有人说这里 可能没有 Tomcat Server 选项

第一种情况就是:你的tomcat插件没启用,这个比较简单,就是 file -> setting -> 搜索tomcat -> 点选中 -> ok

第二种情况就是:你不点下图中的加号时,可以在defaulst中找到tomcat

配置Configurations

接下来在Edit Configurations面板的左上角点击加号,里面就有tomcat了。

在第二个选项卡Deployment中,右边有个绿色 + 加一个Artifact (这个就是访问时候的逻辑根路径)例如我配置的是/abc则访问路径为

http://localhost:8080/abc/

转换为Maven工程

  1. 项目上右键 Add Framework Support。

  2. 选择maven,点击OK。

可以看到在工程根目录下面生成了一个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>java.com.test.irain</groupId>
    <artifactId>TestWeb</artifactId>
    <version>1.0-SNAPSHOT</version>

    
</project>

开始work

依赖Servlet规范包

<?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>java.com.test.irain</groupId>
    <artifactId>TestWeb</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
        </dependency>
        
    </dependencies>
</project>

扩展库目录

新建Post请求

<body style="margin-left: 50px;">
hello world, i'm successed! haha
<form action="test" method="post">
    <button type="submit" value="测试按钮"  style="width:100px;height:40px;margin-left: 40px;">测试</button>
</form>
</body>

创建Servlet

在刚刚依赖的maven库中我们依赖了javax.servlet,打开它的源码发现Servlet定义了5个接口方法。

public interface Servlet {

    //负责初始化servlet对象。容器一旦创建好servlet对象后,就调用此方法来初始化servlet对象。
    void init(ServletConfig var1) throws ServletException;

    //返回servlet对象初始化参数信息
    ServletConfig getServletConfig();

    //响应客户请求,提供服务。
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    //返回一个字符串,字符串中包含servlet的创建者,版本和版权等信息。
    String getServletInfo();

    //释放servlet占用的资源,销毁servlet对象。
    void destroy();
}

我们碰到的大多数 Java servlet 都是为响应 Web 应用程序上下文中的 HTTP 请求而设计的。因此,javax.servlet 和 javax.servlet.http 包中特定于 HTTP 的类是我们应该关心的。

在创建一个 Java servlet 时,一般需要子类 HttpServlet。该类中的方法允许您访问请求和响应包装器(wrapper),您可以用这个包装器来处理请求和创建响应。

public class TestServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, 
            HttpServletResponse resp) throws ServletException, IOException {
        String buttonValue = req.getParameter("button");
        System.out.println("buttonValue = " + buttonValue);
    }
}

配置web.xml的servlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
         version="4.0">

    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>com.test.irain.TestServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
</web-app>

该文件向 Tomcat 定义了 Web 应用程序。该文件中的 servlet-name 元素命名了所使用的 servlet。servlet-class 元素将该名称映射到一个特定的类,该类定义了 servlet,即 HelloWorldServlet(本示例中)。servlet-mapping 元素告诉 Tomcat /test(本例中)形式的 URL 映射我们的 servlet,这是由映射的 servlet 类定义的。

一旦设置好该文件,就可以启动 Tomcat 并能看到 servlet 加载。

运行结果

控制台输出结果:

buttonValue = 测试按钮

Spring MVC 架构

顾名思义,Spring MVC是基于MVC框架的, 为解决持久层中一直未处理好的数据库事务的编程,又为了迎合 NoSQL 的强势崛起,Spring MVC 给出了方案:

SpringMVC架构

小试牛刀

接下来将我们的工程转为spring mvc工程:

  1. 项目上右键 Add Framework Support。

  2. 选择spring mvc,点击OK。

WEB-INFO目录多了两个xml文件:

│  index.jsp
│  index2.html
│
└─WEB-INF
    │  applicationContext.xml
    │  dispatcher-servlet.xml
    │  web.xml
    │
    └─lib

修改web.xml中的url-pattern 元素的值改为 / ,表示要拦截所有的请求,并交由Spring MVC的后台控制器来处理,改完之后:

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

修改dispatcher-servlet.xml文件

这个文件名的开头 dispatcher 与上面 web.xml 中的 <servlet-name> 元素配置的 dispatcher 对应,这是 Spring MVC 的映射配置文件(xxx-servlet.xml),我们编辑如下:

<bean id="simpleUrlHandlerMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <!-- /hello 路径的请求交给 id 为 helloController 的控制器处理-->
            <prop key="/hello">helloController</prop>
        </props>
    </property>
</bean>
<bean id="helloController" class="com.test.irain.controller.HelloController"></bean>

编写 HelloController

public class HelloController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
                                      HttpServletResponse httpServletResponse) throws Exception {
        //Spring MVC 通过 ModelAndView 对象把模型和视图结合在一起
        ModelAndView mav = new ModelAndView("index.jsp");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

修改index.jsp文件如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<h1>${message}</h1>

重启服务器,输入地址:localhost/abc/hello

过程分析

SpringMVC过程分析

第一步:DispatcherServlet拦截请求

从请求离开浏览器以后,第一站到达的就是 DispatcherServlet,看名字这是一个 Servlet,通过 J2EE 的学习,我们知道 Servlet 可以拦截并处理 HTTP 请求,DispatcherServlet 会拦截所有的请求,并且将这些请求发送给 Spring MVC 控制器。

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

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

第二步:处理器映射

处理器映射会根据请求所携带的 URL 信息来进行决策,例如上面的例子中,我们通过配置 simpleUrlHandlerMapping 来将 /hello 地址交给 helloController 处理。

第三步:控制器处理

一旦选择了合适的控制器, DispatcherServlet 会将请求发送给选中的控制器,到了控制器,请求会卸下其负载(用户提交的请求)等待控制器处理完这些信息。

第四步:返回 DispatcherServlet

当控制器在完成逻辑处理后,通常会产生一些信息,这些信息就是需要返回给用户并在浏览器上显示的信息,它们被称为模型(Model)。仅仅返回原始的信息时不够的——这些信息需要以用户友好的方式进行格式化,一般会是 HTML,所以,信息需要发送给一个视图(view),通常会是 JSP。

第五步:视图解析器

上面的例子是直接绑定到了 index.jsp 视图,实际中我们传递给 DispatcherServlet 的视图名并不直接表示某个特定的 JSP。(实际上,它甚至不能确定视图就是 JSP)相反,它传递的仅仅是一个逻辑名称,这个名称将会用来查找产生结果的真正视图。

注解配置

在 dispatcher-servlet.xml 文件中,删掉之前的配置,然后增加一句组件扫描:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描controller下的组件 -->
    <context:component-scan base-package="com.test.irain.controller"/>
</beans>

把接口实现去掉,并添加两个注解

@org.springframework.stereotype.Controller
public class HelloController{

    @RequestMapping("/hello")
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
                                      HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mav = new ModelAndView("index.jsp");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

这RequestMapping还可以作用在类上面,就相当于是给该类所有配置的映射地址前加上了一个地址。