共计 9168 个字符,预计需要花费 23 分钟才能阅读完成。
1.Java Web 模块构造
JSP 文件和 AXPX 文件相似,门路和 URL 一一对应,都会被动静编译为独自 class。Java Web 和 ASP.NET 的外围是别离是 Servlet 和 IHttpHandler 接口,因而无论是根底的 Page 文件(JSP、ASPX)形式还是起初倒退的 MVC 形式(Spring MVC、ASP.NET MVC)都是基于外围接口的根底上再次封装和扩大(DispatcherServlet、MvcHandler)。
Javaweb 我的项目实战教程在线观看(全程干货):https://www.bilibili.com/vide…
除 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 是咱们必须理解和把握的。
|--Assembly Root
|---WEB-INF/
|--web.xml
|--lib/
|--classes/
- WEB-INF 目录:Java Web 文件的根目录。
- web.xml 文件:配置文件 (asp.net web.config)。
- lib 目录:寄存类库文件 (asp.net bin)。
- classes 目录:寄存 class 文件 (asp.net bin)。
2.Java Web 我的项目的根本构造
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
|--Deployment Desciptor
|--JAX-WS Web Services
|--Java Resources
|--JavaScript Resources
|--build
|--WebContent
|--META-INF/
|--MANIFEST.MF
|--WEB-INF/
|--web.xml
|--lib/
- .settings 为 Eclipse 我的项目文件夹,寄存了 Eslipse 我的项目的各种配置。在 Eclipse 我的项目视图中不可见。
- src 目录寄存源码。在 Eclipse 的我的项目视图中对应为 Java Resources/src。
- build 寄存编译后的文件。
- 能够在相似的\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/
- pom.xml:maven 我的项目配置文件。
- .project 文件和.classpath 文件以及.settings 目录和 target/m2e-wtp 目录下的文件为 Eclipse 我的项目配置文件。
- src 和 target:maven 规范我的项目目录。
Eclipse4.5.1 中对应的我的项目资源管理视图
|--MavenWP
|--Deployment Desciptor/
|--Java Resources/
|--JavaScript Resources/
|--Deployed Resources/
|--src
|--target
|--pom.xml
- 默认创立的我的项目会增加一个 index.jsp 并报错:应用 maven 搜寻并增加 servlet 依赖更新后就能够失常运行。
- Java 构建门路问题正告:应用 maven 搜寻并增加 compiler 插件并配置 configuration 节点更新就能够打消。
- 墙的问题配置 maven 镜像,我采纳的是 http://maven.oschina.net/cont…。
- 默认创立的 maven webapp 短少的 src/main/java、src/test/java 和 src/test/resources 等目录须要本人手动增加。
- 批改.settings/org.eclipse.wst.common.project.facet.core.xml,更新 <installed facet=”jst.web” version=”3.1″/>。
- web.xml 根节点开始局部批改如下:
<?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_3_1.xsd"
version="3.1">
Maven 的配置文件 pom.xml:
<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/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>MavenWP Maven Webapp</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 中的一些外围项对应如下:
Servlet 和 ASP.NET 的简化示意图:
用于简化 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 办法):
(1)Servlet 容器启动时查找 ServletContainerInitializer 的实例。
(2)ServletContainerInitializer 实例应用 HandlesTypes 标注一个或多个类型,Servlet 容器将在启动时扫描 classpath,获取这些类型的实例。
(3)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。
同理,Java Servlet 中应用自定义 Session 通过 Filter 能够实现。因为不同的 servlet 容器对 Session 的实现不同,所以通用性最好的形式是继承 HttpServletRequestWrapper 重写 getSession 办法返回自定义的 Session 对象。Filter 采纳了职责链模式(chain of responsibility),HttpServletRequestWrapper 采纳了装璜模式(Decorator),能够通过《Head First 设计模式》浏览模式的相干内容。
(1)首先自定义继承 HttpSession 的 MySession(为了便于演示,仅包装了容器的 session 并转发调用)。
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
public class MySession implements HttpSession {
private HttpSession _containerSession;
public MySession(HttpSession session) {this._containerSession = session;}
@Override
public long getCreationTime() {return this._containerSession.getCreationTime();
}
@Override
public String getId() {return this._containerSession.getId();
}
@Override
public long getLastAccessedTime() {return this._containerSession.getLastAccessedTime();
}
@Override
public ServletContext getServletContext() {return this._containerSession.getServletContext();
}
@Override
public void setMaxInactiveInterval(int interval) {this._containerSession.setMaxInactiveInterval(interval);
}
@Override
public int getMaxInactiveInterval() {return this._containerSession.getMaxInactiveInterval();
}
@SuppressWarnings("deprecation")
@Override
public HttpSessionContext getSessionContext() {return this._containerSession.getSessionContext();
}
@Override
public Object getAttribute(String name) {return this._containerSession.getAttribute(name);
}
@SuppressWarnings("deprecation")
@Override
public Object getValue(String name) {return this._containerSession.getValue(name);
}
@Override
public Enumeration<String> getAttributeNames() {return this._containerSession.getAttributeNames();
}
@SuppressWarnings("deprecation")
@Override
public String[] getValueNames() {return this._containerSession.getValueNames();
}
@Override
public void setAttribute(String name, Object value) {this._containerSession.setAttribute(name, value);
}
@SuppressWarnings("deprecation")
@Override
public void putValue(String name, Object value) {this._containerSession.putValue(name, value);
}
@Override
public void removeAttribute(String name) {this._containerSession.removeAttribute(name);
}
@SuppressWarnings("deprecation")
@Override
public void removeValue(String name) {this._containerSession.removeValue(name);
}
@Override
public void invalidate() {this._containerSession.invalidate();
}
@Override
public boolean isNew() {return this._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 {
public MyRequest() {super(null);
}
public MyRequest(HttpServletRequest request) {super(request);
// TODO 主动生成的构造函数存根
}
@Override
public HttpSession getSession(boolean create) {return new MySession(super.getSession(create));
}
@Override
public HttpSession getSession() {return new MySession(super.getSession());
}
}
(3)自定义 Filter 将 Request 包装为 MyRequest
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {// TODO 主动生成的办法存根}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {chain.doFilter(new MyRequest((HttpServletRequest) request), response);
}
@Override
public void destroy() {// 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