JavaWeb项目学习笔记-入门Javaweb最强教程

简介: Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有Java Applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如Servlet,JSP、第三方框架等等。

     Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有Java Applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如Servlet,JSP、第三方框架等等。Java技术对Web领域的发展注入了强大的动力。今天就来学习javaweb!!!go go go~

Javaweb项目实战教程在线观看(全程干货):https://www.bilibili.com/video/BV1Z3411C7NZ/

1.Java Web 模块结构

      JSP文件和AXPX文件类似,路径和URL一一对应,都会被动态编译为单独class。Java Web和ASP.NET的核心是分别是Servlet和IHttpHandler接口,因此无论是基础的Page文件(JSP、ASPX)方式还是后来发展的MVC方式(Spring MVC、ASP.NET MVC)都是基于核心接口的基础上再次封装和扩展(DispatcherServlet、MvcHandler)。

    除JSP文件外,其他全部文件部署在应用目录的WEB-INF子目录下,WEB-INF目录可以认为是ASP.NET中将web.config文件、bin目录和App_开头的运行时目录存放在了一个统一的根目录中。

     Java Web的配置文件web.xml也存放在WEB-INF目录下,而ASP.NET的配置文件web.config一般直接存放在应用目录下(ASP.NET其他目录同样可以有web.config文件)。ASP.NET将所有的引用和代码生成的dll都部署在bin中,而Java Web的引用jar和生成的class分别存放在WEB-INF的子目录lib和classes中。

      综上,类似ASP.NET中的web.config、bin、App_Data等,Java Web中的WEB-INF、web.xml、lib和classes是我们必须了解和掌握的。

|--AssemblyRoot|---WEB-INF/|--web.xml|--lib/|--classes/

2.Java Web项目的基本结构[Eclipse Dynamic Web Project]

Eclipse Dynamic Web Project项目

(1)可以配置需要编译的源码目录和输出目录,默认编译src目录下的源文件到build\classes目录下。

(2)可以配置WEB-INF的根目录,默认为WebContent。

(3)可以选择是否生成默认web.xml文件。

我们创建一个命名为DynamicWP的默认生成web.xml的Dynamic Web Proejct项目。文件结构如下:

|--DynamicWP|--.settings/|--build/|--classes/|--src/|--WebContent/|--META-INF/|--MANIFEST.MF|--WEB-INF/|--web.xml|--lib/

在Eclipse的项目资源管理器中DyanmicWP项目的视图如下:

|--DynamicWP|--DeploymentDesciptor|--JAX-WSWebServices|--JavaResources|--JavaScriptResources|--build|--WebContent|--META-INF/|--MANIFEST.MF|--WEB-INF/|--web.xml|--lib/
  1. settings为Eclipse项目文件夹,存放了Eslipse项目的各种配置。在Eclipse项目视图中不可见。
  2. src目录存放源码。在Eclipse的项目视图中对应为Java Resources/src。
  3. build存放编译后的文件。
  4. 可以在类似的\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\DynamicWP目录中查看运行时的文件结构。

3.Maven Web项目的基本结构

     鉴于目前Java IDE众多并且都有一定的拥泵,Eclipse的Java Web项目不具有可移植性。Maven即解决了项目结构的规范问题又提供了强大引用处理等强大的功能,在项目布局等方面已经是目前事实上的标准。Maven项目的主要结构如下:

|--root|--pom.xml|--src/|--main/|--java/|--resources/|--webapp/|--test/|--java/|--resources|--target/

Eclipse中新建一个Maven web app项目。文件结构如下:

|--MavenWP|--pom.xml|--.project|--.classpath|--.settings/|--src/|--target/|--classes/|--m2e-wtp/
  1. pom.xml:maven项目配置文件。
  2. .project文件和.classpath文件以及.settings目录和target/m2e-wtp目录下的文件为Eclipse项目配置文件。
  3. src和target:maven标准项目目录。

Eclipse4.5.1中对应的项目资源管理视图

|--MavenWP|--DeploymentDesciptor/|--JavaResources/|--JavaScriptResources/|--DeployedResources/|--src|--target|--pom.xml
  • 默认创建的项目会添加一个index.jsp并报错:使用maven搜索并添加servlet依赖更新后就可以正常运行。
  • Java构建路径问题警告:使用maven搜索并添加compiler插件并配置configuration节点更新就可以消除。
  • 墙的问题配置maven镜像,我采用的是http://maven.oschina.net/content/groups/public/。
  • 默认创建的maven webapp缺少的src/main/java、src/test/java和src/test/resources等目录需要自己手动添加。
  • 修改.settings/org.eclipse.wst.common.project.facet.core.xml,更新。
  • web.xml根节点开始部分修改如下:
<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="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_3_1.xsd"version="3.1">

Maven的配置文件pom.xml:

<projectxmlns="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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>me.test</groupId><artifactId>MavenWP</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>MavenWPMavenWebapp</name><url>http://maven.apache.org</url><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>3.1.0</version></dependency></dependencies><build><finalName>MavenWP</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.3</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build></project>

4.servlet基础

正如ASP.NET的核心是IHttpHandler一样,Java Web的核心是Servlet接口,位于javax.servlet命名空间中。Filter的概念可以参考ASP.NET的HttpModule,Servlet中的各种Listener可以参考ASP.NET HttpApplicaiton中类似的event。无论是Java还是.NET的Web技术,都是基于HTTP协议的具体实现。Java Web和ASP.NET中的一些核心项对应如下:

图片.png

Servlet和ASP.NET的简化示意图:

图片.png

用于简化web.xml配置的Servlet的注解(3.0开始支持,在ASP.NET中没有对应项):

(1)WebServlet:作用在javax.servlet.http.HttpServlet的实现类上。

(2)WebFilter:作用在javax.servlet.Filter的实现类上。

(3)WebListener:作用在Listener的实现类上(javax.servlet.ServletContextListener、javax.servlet.ServletContextAttributeListener、javax.servlet.ServletRequestListener、javax.servlet.ServletRequestAttributeListener、javax.servlet.http.HttpSessionListener、javax.servlet.http.HttpSessionAttributeListener)。

(4)WebInitParam:结合WebServlet和WebFilter注解用来配置属性。

(5)MultipartConfig:作用在javax.servlet.http.HttpServlet的实现类上。标注请求是mime/multipart类型。

用于Servlet容器初始化的ServletContainerInitializer(可实现无web.xml,3.0开始支持,可类比ASP.NET的Application_Start方法):

  • Servlet容器启动时查找ServletContainerInitializer的实例。

  • ServletContainerInitializer实例使用HandlesTypes标注一个或多个类型,Servlet容器将在启动时扫描classpath,获取这些类型的实例。

  • Servlet容器在启动时调用ServletContainerInitializer实现类的onStartup方法,该方法可以获取HandlesTypes标注的所有类型对象。

5.自定义Session

     Session在存储安全性要求较高的会话信息方面是必不可少的,Session当然绝对不是用来存储用户登录状态的,但类似验证码等敏感信息却必须存储在Session中。对于分布式Web应用自定义Session支持独立的状态服务器或集群是必须的。

     ASP.NET通过SessionStateModule通过配置文件配置实际的Session提供程序,Session提供程序实现了SessionStateStoreProviderBase,因此在ASP.NET中实现自定义Session是通过继承SessionStateStoreProviderBase实现,配置Session是通过Web.config。ASP.NET自定义session的代码参考github上的开源项目SQLiteSessionStateStore。

图片.png

同理,Java Servlet中使用自定义Session通过Filter可以实现。由于不同的servlet容器对Session的实现不同,所以通用性最好的方式是继承HttpServletRequestWrapper重写getSession方法返回自定义的Session对象。Filter采用了职责链模式(chain of responsibility),HttpServletRequestWrapper采用了装饰模式(Decorator),可以通过《Head First 设计模式》阅读模式的相关内容。

(1)首先自定义继承HttpSession的MySession(为了便于演示,仅包装了容器的session并转发调用)。

importjava.util.Enumeration;
importjavax.servlet.ServletContext;
importjavax.servlet.http.HttpSession;
publicclassMySessionimplementsHttpSession {
privateHttpSession_containerSession;
publicMySession(HttpSessionsession) {
this._containerSession=session;
    }
@OverridepubliclonggetCreationTime() {
returnthis._containerSession.getCreationTime();
    }
@OverridepublicStringgetId() {
returnthis._containerSession.getId();
    }
@OverridepubliclonggetLastAccessedTime() {
returnthis._containerSession.getLastAccessedTime();
    }
@OverridepublicServletContextgetServletContext() {
returnthis._containerSession.getServletContext();
    }
@OverridepublicvoidsetMaxInactiveInterval(intinterval) {
this._containerSession.setMaxInactiveInterval(interval);
    }
@OverridepublicintgetMaxInactiveInterval() {
returnthis._containerSession.getMaxInactiveInterval();
    }
@SuppressWarnings("deprecation")
@OverridepublicHttpSessionContextgetSessionContext() {
returnthis._containerSession.getSessionContext();
    }
@OverridepublicObjectgetAttribute(Stringname) {
returnthis._containerSession.getAttribute(name);
    }
@SuppressWarnings("deprecation")
@OverridepublicObjectgetValue(Stringname) {
returnthis._containerSession.getValue(name);
    }
@OverridepublicEnumeration<String>getAttributeNames() {
returnthis._containerSession.getAttributeNames();
    }
@SuppressWarnings("deprecation")
@OverridepublicString[] getValueNames() {
returnthis._containerSession.getValueNames();
    }
@OverridepublicvoidsetAttribute(Stringname, Objectvalue) {
this._containerSession.setAttribute(name, value);
    }
@SuppressWarnings("deprecation")
@OverridepublicvoidputValue(Stringname, Objectvalue) {
this._containerSession.putValue(name, value);
    }
@OverridepublicvoidremoveAttribute(Stringname) {
this._containerSession.removeAttribute(name);
    }
@SuppressWarnings("deprecation")
@OverridepublicvoidremoveValue(Stringname) {
this._containerSession.removeValue(name);
    }
@Overridepublicvoidinvalidate() {
this._containerSession.invalidate();
    }
@OverridepublicbooleanisNew() {
returnthis._containerSession.isNew();
    }
}

2)自定义继承HttpServletRequestWrapper的MyRequest import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpSession;

public class MyRequest extends HttpServletRequestWrapper {

publicMyRequest() {
super(null);
}
publicMyRequest(HttpServletRequestrequest) {
super(request);
// TODO 自动生成的构造函数存根}
@OverridepublicHttpSessiongetSession(booleancreate) {
returnnewMySession(super.getSession(create));
}
@OverridepublicHttpSessiongetSession() {
returnnewMySession(super.getSession());
}
}

(3)自定义Filter将Request包装为MyRequest

importjava.io.IOException;
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.annotation.WebFilter;
importjavax.servlet.http.HttpServletRequest;
@WebFilter("/*")
publicclassMyFilterimplementsFilter {
@Overridepublicvoidinit(FilterConfigfilterConfig) throwsServletException {
// TODO 自动生成的方法存根    }
@OverridepublicvoiddoFilter(ServletRequestrequest, ServletResponseresponse, FilterChainchain)
throwsIOException, ServletException {
chain.doFilter(newMyRequest((HttpServletRequest) request), response);
    }
@Overridepublicvoiddestroy() {
// TODO 自动生成的方法存根    }
}

通过注解配置了Filter,也可以通过原始的web.xml方式配置。

到这里就告一段落啦!!!下面是上文的小总结:

(1)配置文件:ASP.NET的web.config和Java的web.xml

(2)Web核心:ASP.NET的IHttpHandler接口和Java的Servlet接口

(3)拦截器:ASP.NET的HttpModule和Java的Filter

(4)应用程序事件:ASP.NET的HttpApplication event和Java的各种Listener

(5)启动器:ASP.NET的Application_Start和Java的ServletContainerInitializer

(6)引用管理:ASP.NET的Nuget和Java的Maven

相关文章
|
7天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
7天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
8天前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
从Java环境的搭建到实际代码的编写,从基本用法的讲解到底层原理的剖析,深度解析Java基础知识。本文是《Java学习路线》专栏的起始文章,旨在提供一套完整的Java学习路线,覆盖Java基础知识、数据库、SSM/SpringBoot等框架、Redis/MQ等中间件、设计模式、架构设计、性能调优、源码解读、核心面试题等全面的知识点,并在未来不断更新和完善,帮助Java从业者在更短的时间内成长为高级开发。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
|
8天前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
本文是Java基础的进阶篇,对异常、集合、泛型、Java8新特性、I/O流等知识进行深入浅出的介绍,并附有对应的代码示例,重要的地方带有对性能、底层原理、源码的剖析。适合Java初学者。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
|
2天前
|
Java API
Java时间戳教程
本文详细介绍Java中时间戳的处理方法,包括获取当前时间戳、使用`java.time`包、时间戳与日期的相互转换及格式化等。示例代码展示了如何利用`System.currentTimeMillis()`和`java.time.Instant`获取时间戳,以及如何通过`Date`和`ZonedDateTime`进行日期转换和时区处理。随着Java 8引入的`java.time`包,日期时间操作变得更加强大和便捷,推荐在新项目中优先采用。
|
8天前
|
SQL JSON JavaScript
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
Vue 指令、生命周期、this和$、vue脚手架进行模块化开发/ElementUI框架、综合案例,element商品列表展示增删改查
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
|
8天前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
本文是“Java学习路线”中Java基础知识的高级篇,主要对多线程和反射进行了深入浅出的介绍,在多线程部分,详细介绍了线程的概念、生命周期、多线程的线程安全、线程通信、线程同步,并对synchronized和Lock锁;反射部分对反射的特性、功能、优缺点、适用场景等进行了介绍。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
|
21天前
|
算法 Java 开发者
Java 编程入门:从零到一的旅程
本文将带领读者开启Java编程之旅,从最基础的语法入手,逐步深入到面向对象的核心概念。通过实例代码演示,我们将一起探索如何定义类和对象、实现继承与多态,并解决常见的编程挑战。无论你是编程新手还是希望巩固基础的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
22天前
|
存储 Java 程序员
Java中的集合框架:从入门到精通
【8月更文挑战第30天】在Java的世界里,集合框架是一块基石,它不仅承载着数据的存储和操作,还体现了面向对象编程的精髓。本篇文章将带你遨游Java集合框架的海洋,从基础概念到高级应用,一步步揭示它的奥秘。你将学会如何选择合适的集合类型,掌握集合的遍历技巧,以及理解集合框架背后的设计哲学。让我们一起探索这个强大工具,解锁数据结构的新视角。
|
9天前
|
Java 程序员
Java中的异常处理:从入门到精通
在Java编程的世界中,异常处理是保持程序稳定性和可靠性的关键。本文将通过一个独特的视角—把异常处理比作一场“捉迷藏”游戏—来探讨如何在Java中有效管理异常。我们将一起学习如何识别、捕捉以及处理可能出现的异常,确保你的程序即使在面对不可预见的错误时也能优雅地运行。准备好了吗?让我们开始这场寻找并解决Java异常的冒险吧!