j2ee标准-servlet3.0引入的新特性

来自:http://www.blogjava.net/freeman1984/archive/2012/11/16/391444.html

Servlet3.0规范的新特性主要是为了3个目的:
1.简化开发
2.便于布署
3.支持Web2.0原则
为了简化开发流程,Servlet3.0引入了注解(annotation),这使得web布署描述符web.xml不在是必须的选择。
Pluggability可插入性
当使用任何第三方的框架,如Struts,JSF或Spring,我们都需要在web.xml中添加对应的Servlet的入口。这使得web描述符笨重而难以维护。Servlet3.0的新的可插入特性使得web应用程序模块化而易于维护。通过web fragment实现的可插入性减轻了开发人员的负担,不需要再在web.xml中配置很多的Servlet入口。
Asynchronous Processing 异步处理
另外一个显著的改变就是Servlet3.0支持异步处理,这对AJAX应用程序非常有用。当一个Servlet创建一个线程来创建某些请求的时候,如查询数据库或消息连接,这个线程要等待直到获得所需要的资源才能够执行其他的操作。异步处理通过运行线程执行其他的操作来避免了这种阻塞。
Apart from the features mentioned here, several other enhancements have been made to the existing API. The sections towards the end of the article will explore these features one by one in detail.
除了这些新特性之外, Servlet3.0对已有的API也做了一些改进,在本文的最后我们会做介绍。
Annotations in Servlet Servlet中使用注解
Servlet3.0的一个主要的改变就是支持注解。使用注解来定义Servlet和filter使得我们不用在web.xml中定义相应的入口。
@WebServlet
@WebServlet用来定义web应用程序中的一个Servlet。这个注解可以应用于继承了HttpServlet。这个注解有多个属性,例如name,urlPattern, initParams,我们可以使用者的属性来定义Servlet的行为。urlPattern属性是必须指定的。
例如我们可以象下面的例子这样定义:

1. @WebServlet(name = “GetQuoteServlet”,  urlPatterns = {“/getquote”} )

2. public class GetQuoteServlet extends HttpServlet {

3.     @Override

4.     protected void doGet(HttpServletRequest request, HttpServletResponse response)

5.             throws ServletException, IOException {

6.         PrintWriter out = response.getWriter();

7.         try {

8.             String symbol = request.getParameter(“symbol”);

9.             out.println(“<h1>Stock Price is</h1>” + StockQuoteBean.getPrice(symbol);

10.         } finally {

11.             out.close();

12.         }

13.     }

14. }

15.

16. public class StockQuoteBean {

17. private StockQuoteServiceEntity serviceEntity = new StockQuoteServiceEntity();

18.     public double getPrice(String symbol) {

19.         if(symbol !=null )  {

20. return serviceEntity.getPrice(symbol);

21.          } else {

22.             return 0.0;

23.         }

24.     }

25. }

复制代码

在上面的例子中,一个Servlet只对应了一个urlPattern。实际上一个Servlet可以对应多个urlPattern,我们可以这样定义:

1. @WebServlet(name = “GetQuoteServlet”,  urlPatterns = {“/getquote”,  “/stockquote”} )

2. public class GetQuoteServlet extends HttpServlet {

3.     @Override

4.     protected void doGet(HttpServletRequest request, HttpServletResponse response)

5.             throws ServletException, IOException {

6.         PrintWriter out = response.getWriter();

7.         try {

8.             String symbol = request.getParameter(“symbol”);

9.             out.println(“<h1>Stock Price is</h1>” + StockQuoteBean.getPrice(symbol);

10.         } finally {

11.             out.close();

12.         }

13.     }

14. }

复制代码

@WebFilter
我们可以使用@WebFilter注解来定义filter。这个注解可以被应用在实现了javax.servlet.Filter接口的类上。同样的,urlPattern属性是必须指定的。下面就是一个例子。

1. @WebFilter(filterName = “AuthenticateFilter”, urlPatterns = {“/stock.jsp”, “/getquote”})

2. public class AuthenticateFilter implements Filter {

3.

4.     public void doFilter(ServletRequest request, ServletResponse response,

5.             FilterChain chain)     throws IOException, ServletException {

6.         String username = ((HttpServletRequest) request).getParameter(“uname”);

7.         String password = ((HttpServletRequest) request).getParameter(“password”);

8.           if (username == null || password == null) {

9.                  ((HttpServletResponse) response).sendRedirect(“index.jsp”);            }

10. if (username.equals(“admin”) && password.equals(“admin”)) {

11.                 chain.doFilter(request, response);      }

12. else {

13.                 ((HttpServletResponse) response).sendRedirect(“index.jsp”);         }

14.          }

15.

16.     public void destroy() {

17.     }

18.     public void init(FilterConfig filterConfig) {

19.     }

20. }

复制代码

@WebInitParam
可以使用@WebInitParam注解来制定Servlet或filter的初始参数。当然我们也可以使用@WebServlet或@WebFileter的initParam属性来指定初始参数。下面是使用@WebInitParam的例子:

1. @WebServlet(name = “GetQuoteServlet”, urlPatterns = {“/getquote”})

2. @WebInitParam(name = “default_market”, value = “NASDAQ”)

3. public class GetQuoteServlet extends HttpServlet {

4.     @Override

5.     protected void doGet(HttpServletRequest request, HttpServletResponse response)

6.             throws ServletException, IOException {

7.         response.setContentType(“text/html;charset=UTF-8”);

8.         PrintWriter out = response.getWriter();

9.         try {

10.             String market = getInitParameter(“default_market”);

11.             String symbol = request.getParameter(“symbol”);

12.             out.println(“<h1>Stock Price in ” + market + ” is</h1>” + StockQuoteBean.getPrice(symbol, market));

13.         } finally {

14.             out.close();

15.         }

16.     }

17. }

复制代码

下面是使用initParam属性的例子:

1. @WebServlet(name = “GetQuoteServlet”,

2.             urlPatterns = {“/getquote”},

3.             initParams={@WebInitParam(name=”default_market”,  value=”NASDAQ”)}

4.            )

5. public class GetQuoteServlet extends HttpServlet {

6.     @Override

7.     protected void doGet(HttpServletRequest request, HttpServletResponse response)

8.             throws ServletException, IOException {

9.         response.setContentType(“text/html;charset=UTF-8”);

10.         PrintWriter out = response.getWriter();

11.         try {

12.             String market = getInitParameter(“default_market”);

13.             String symbol = request.getParameter(“symbol”);

14.             out.println(“<h1>Stock Price in ” + market + ” is</h1>” + StockQuoteBean.getPrice(symbol, market));

15.         } finally {

16.             out.close();

17.         }

18.     }

19. }

复制代码

@WebListener
@WebListener注解被应用在作为listener监听web应用程序事件的类上,所以@WebListener能够被应用在实现了ServletContextListener,ServletContextAttributeListener,ServletRequestListener,ServletRequestAttributeListener,HttpSessionListener和HttpSessionAttributeListener接口的类上。在下面的例子中,该类实现了ServletContextListener接口。

1. @WebListener

2. public class QuoteServletContextListener implements ServletContextListener {

3.    public void contextInitialized(ServletContextEvent sce) {

4.    ServletContext context = sce.getServletContext();

5. context.setInitParameter(“default_market”, “NASDAQ”);

6. }

7. public void contextDestroyed(ServletContextEvent sce) {

8. }

9. }

复制代码

@MultipartConfig
使用@MultipartConfig注解来指定Servlet要求的multipart MIME类型。这种类型的MIME附件将从request对象中读取。
The Metadata and Common Annotations元数据与通用的注解
除了以上的Servlet特定的注解之外,Servlet3.0还支持JSR175(Java元数据规范)和JSR250(Java平台通用注解)所规定的注解,包括:
* 安全相关的注解,如 @DeclareRoles 和 @RolesAllowed
* 使用EJB的注解,如 @EJB 和 @EJBs
* 资源注入相关的注解,如 @Resource 和 @Resources
* 使用JPA的注解,如 @PersistenceContext, @PersistenceContexts, @PersistenceUnit, 和 @PersistenceUnits
* 生命周期的注解,如 @PostConstruct和 @PreDestroy
* 提供WebService引用的注解,如 @WebServiceRef and @WebServiceRefs
注解和web.xml哪个会生效
注解的引入使得web.xml变成可选的了。但是,我们还是可以使用web.xml。容器会根据web.xml中的metadata-complete元素的值来决定使用web.xml还是使用注解。如果该元素的值是true,那么容器不处理注解,web.xml是所有信息的来源。如果该元素不存在或者其值不为true,容器才会处理注解。
Web框架的可插入性
我们前面说过了Servlet3.0的改进之一就是使得我们能够将框架和库插入到web应用程序中。这种可插入性减少了配置,并且提高了web应用程序的模块化。Servlet3.0是通过web模块布署描述片段(简称web片段)来实现插入性的。
一个web片段就是web.xml文件的一部分,被包含在框架特定的Jar包的META-INF目录中。Web片段使得该框架组件逻辑上就是web应用程序的一部分,不需要编辑web布署描述文件。
Web片段中使用的元素和布署文件中使用的元素基本相同,除了根元素不一样。Web片段的根元素是<web-fragment>,而且文件名必须叫做web-fragment.xml。容器只会在放在WEB-INF\lib目录下的Jar包中查找web-fragment.xml文件。如果这些Jar包含有web-fragment.xml文件,容器就会装载需要的类来处理他们。
在web.xml中,我们要求Servlet的name必须唯一。同样的,在web.xml和所有的web片段中,Servlet的name也必须唯一。
下面就是一个web-fragment的例子:
web-fragment.xml

1. <web-fragment>

2. <servlet>

3. <servlet-name>ControllerServlet</servlet-name>

4. <servlet-class>com.app.control.ControllerServlet</servlet-class>

5. </servlet>

6. <listener>

7. <listener-class>com.listener.AppServletContextListener</listener-class>

8. </listener>

9. </web-fragment>

复制代码

框架的Jar包是放在WEB-INF\lib目录下的,但是Servlet3.0提供两种方法指定多个web片段之间的顺序:
1. 绝对顺序
2. 相对顺序
我们通过web.xml文件中的<absolute-ordering>元素来指定绝对顺序。这个元素有之元素name,name的值是各个web片段的name元素的值。这样就指定了web片段的顺序。如果多个web片段有相同的名字,容器会忽略后出现的web片段。下面是一个指定绝对顺序的例子:
web.xml

1. <web-app>

2. <name>DemoApp</name>

3. <absolute-ordering>

4. <name>WebFragment1</name>

5. <name>WebFragment2</name>

6. </absolute-ordering>

7. …

8. </web-app>

复制代码

相对顺序通过web-fragment.xml中的<ordering>元素来确定。Web片段的顺序由<ordering>的子元素<before>,<after>和<others>来决定。当前的web片段会放在所有的<before>元素中的片段之前。同样的,会放在所有的<after>元素中的片段之后。<others>用来代替所有的其他片段。注意只有当web.xml中没有<absolute-ordering>时,容器才会使用web片段中定义的相对顺序。
下面是一个帮助理解相对顺序的例子:
web-fragment.xml

1. <web-fragment>

2. <name>WebFragment1</name>

3. <ordering><after>WebFragment2</after></ordering>

4. …

5. </web-fragment>

复制代码

web-fragment.xml

1. <web-fragment>

2. <name>WebFragment2</name>

3. ..

4. </web-fragment>

复制代码

web-fragment.xml

1. <web-fragment>

2. <name>WebFragment3</name>

3. <ordering><before><others/></before></ordering>

复制代码

..
</web-fragment>
这些文件将会按照下面的顺序被处理:
1. WebFragment3
2. WebFragment2
3. WebFragment1
包含WebFragment3的Jar文件被最先处理,包含WebFragment2的文件被第二个处理,包含WebFragment1的文件被最后处理。
如果既没有定义绝对顺序,也没有定义相对顺序,那么容器就认为所有的web片段间没有顺序上的依赖关系。
Servlet中的异步处理
很多时候Servlet要和其他的资源进行互动,例如访问数据库,调用web service。在和这些资源互动的时候,Servlet不得不等待数据返回,然后才能够继续执行。这使得Servlet调用这些资源的时候阻塞。Servlet3.0通过引入异步处理解决了这个问题。异步处理允许线程调用资源的时候不被阻塞,而是直接返回。AsyncContext负责管理从资源来的回应。AsyncContext决定该回应是应该被原来的线程处理还是应该分发给容器中其他的资源。AsyncContext有一些方法如start,dispatch和complete来执行异步处理。
要想使用Servlet3.0的异步处理,我们需要设置@Webservlet和@WebFilter注解的asyncSupport属性。这个属性是布尔值,缺省值是false。
Servlet3.0的异步处理可以很好的和AJAX配合。在Servlet的init方法中,我们能够访问数据库或从JMS读取消息。在doGet或doPost方法中,我们能够启动异步处理,AsyncContext会通过AsyncEvent和AsyncListener来管理线程和数据库操作/JMS操作自己的关系。
已有API的改进
除了这些新特性之外,Servlet3.0还对以往已经存在的API做了一些改进。
HttpServletRequest
To support the multipart/form-data MIME type, the following methods have been added to the HttpServletRequest interface:
为了支持multipart/form-data MIME类型,在HttpServletRequest接口中添加了项目的方法:
* Iterable<Part> getParts()
* Part getPart(String name)
Cookies
为了避免一些跨站点攻击,Servlet3.0支持HttpOnly的cookie。HttpOnly cookie不想客户端暴露script代码。Servlet3.0在Cookie类中添加了如下的方法来支持HttpOnly cookie:
* void setHttpOnly(boolean isHttpOnly)
* boolean isHttpOnly()
ServletContext
通过在ServletContext中添加下面的方法,Servlet3.0允许Servlet或filter被编程的加入到context中:
* addServlet(String servletName, String className)
* addServlet(String servletName, Servlet servlet)
* addServlet(String servletName, Class<? extends Servlet> servletClass)
* addFilter(String filterName, String className)
* addFilter(String filterName, Filter filter)
* addFilter(String filterName, Class<? extends Filter>filterClass)
* setInitParameter (String name, String Value)

Servlet3.0新功能: 异步处理

J2EE 6和Glassfish 3V正式发布了,J2EE 6正式发布了Servlet3.0, 为了能更好的对WEB2.0提供支持, 3.0添加了异步处理的机制.

 

HTTP1.1相对于HTTP1.0的影响.

 

HTTP1.1最大的一个改变就是提供了长连接,这样HTTP不再是一次请求,一次连接的协议了,只要HTTP的connection不关闭,一次HTTP连接可以支持任意多次request/reponse处理. 当WEB Client与WEB Server建立连接时,客户端可以采用长连接,也就是说Client会一直保持对WEB Server的连接(例如:Browser对一个网站保持当连接,知道Browser关闭或最终退出该网站). 旧的WEB Server会为每一个Http连接分配一个active的Thread,这样当Client的数量增大时,Server端Thread Pool的最大容量也需要相应增大,但Thread是相当耗内存的,一个不小心就会导致Server端NotEnoughMemory…

 

基于HTTP1.1,大部分支持Servlet2.X的WEB容器都采用的NIO去接收和处理请求. 当Client和Server端建立连接时,Server端并不分配一个Thread给HTTP连接.直到Server端收到Client端发送的Request时, Server才开始为该Request分配Thread(注意:这里不是为HTTP连接分配Thread).

 

这样当大量的Client建立长连接与Server进行交互时,Server无需维持一个Thread给inactive的HTTP长连接, 每个Servlet在doReceived()时其实对应的是一个active Request,而不是HTTPConnection本身. 这样Server端所需的最大Thread数大大地减少了.

 

AJAX的影响

 

1. Request的数量爆炸性增加增加

 

过去WEB Browser打开一个Web page,只需要和Web Server端建立一个HTTP连接.但AJAX技术出现以后,一个Web page上可能有多个与Web Server的连接,而且Ajax request通常是十分频繁的,Server接收到的Request数量大大增长了, 这样原先NIO的技术已经不能很好的支持基于Ajax的服务了.

 

Servlet 3.0的异步处理就能够解决上面的问题.

 

Servlet3.0的solution:

当request发送到Server端时,servlet的doReceived()将request放进一个queue里,然后doReceived结束.这个时候server并没有关闭response,Client端一直在等server端response的内容. Server端维护自己的ThreadPool,当ThreadPool里有idle的Thread,就从queue里取出一个request,分配idle的Thread给request,并进行处理.

 

Java代码 
  1.    @WebServlet(“/test” asyncSupported=true)
  2.    public class MyServlet extends HttpServlet {
  3.        ScheduledThreadPoolExecutor executor = null;
  4.         public void init(ServletConfig arg0) throws ServletException {
  5.                    executor = new ThreadPoolExecutor(10);//独立的线程池处理请求
  6.         }
  7.         public void doGet(HttpServletRequest req, HttpServletResponse res) {
  8.             …
  9.             AsyncContext aCtx = request.startAsync(req, res);
  10.             executor.execute(new AsyncWebService(aCtx));//异步处理
  11.         }
  12.    }
  13.    public class AsyncWebService implements Runnable {
  14.         AsyncContext ctx;
  15.         public AsyncWebService(AsyncContext ctx) {
  16.             this.ctx = ctx;
  17.         }
  18.         public void run() {//处理请求
  19.             //Do something here …
  20.             // Dispatch the request to render the result to a JSP.
  21.             ctx.dispatch(“/render.jsp”);
  22.    }
  23. }
   @WebServlet("/test" asyncSupported=true)   public class MyServlet extends HttpServlet {       ScheduledThreadPoolExecutor executor = null;        public void init(ServletConfig arg0) throws ServletException {                   executor = new ThreadPoolExecutor(10);//独立的线程池处理请求        }        public void doGet(HttpServletRequest req, HttpServletResponse res) {            ...            AsyncContext aCtx = request.startAsync(req, res);            executor.execute(new AsyncWebService(aCtx));//异步处理        }   }   public class AsyncWebService implements Runnable {        AsyncContext ctx;        public AsyncWebService(AsyncContext ctx) {            this.ctx = ctx;        }        public void run() {//处理请求            //Do something here ...            // Dispatch the request to render the result to a JSP.            ctx.dispatch("/render.jsp");   }}

以上的例子可以用于处理对Ajax的请求,因为通常Ajax的请求多,但对响应速度的要求并不太高. 对于正常的页面请求,要求一定的响应速度,可以沿用以前Servlet同步的实现.

 

2. Server端推送信息

在Web2.0的应用中, Ajax可用通过不断的发送Request来获取Server端某种信息的变化,但这种实现会产生大量的Client请求. 当前推荐的方法是,让Server端自己推送信息变化给Client.

 

因为Servlet3.0提供了异步处理的方式, Request提交给Server以后, Server可以为Request注册一个Listener,由Listener去monitor信息的变化,当信息发生变化时,由Listener负责把信息变化发送给Cient(Listener关闭HTTP response).

j2ee标准-web.xml中的web-app标签分析

当用eclipse创建 dynamic web project 时,创建过程中  需要选择一个 dynamic web module version 。当前可选择的取值有 2.2    2.3   2.4   2.5   3.0   3.1  取值完毕时  ,项目中的   web.xml  里面的   web-app 版本 就是   dynamic web module version 值。  这个值 其实 就是 servlet 版本值。(servlet 版本升级,都会带来一些新的功能)

每个tomcat版本对应的标准servlet版本,如下:

The XSD version is preferred since JSP 2.0 / Servlets 2.4 (eg: Tomcat 5.5). Note that the XML encoding can be specified as ISO-8859-1, UTF-8, or any other valid encoding in either version, and should match the actual encoding of your text file.

注意 servlet 2.4、3.1之后xsi的变化。

Servlet 3.1 deployment descriptor

<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">
</web-app>

XSD example for JSP 2.2 / Servlets 3.0 (Tomcat 7.0):

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

</web-app>

XSD example for JSP 2.1 / Servlets 2.5 (Tomcat 6.0):

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     version="2.5">

</web-app>

XSD example for JSP 2.0 / Servlets 2.4 (Tomcat 5.5):

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
     version="2.4">

</web-app>

DTD example for JSP 1.2 / Servlets 2.3 (Tomcat 5):

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE web-app
   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

</web-app>&nbsp;

官方参考可见http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html。

对于spring,对应关系如下:
  • 4.0 最低要求JDK 6,支持websocket, Servlet 3.0+
  • 3.0 最低要求JDK 1.5,基于注解的配置,servlet 2.4,完全支持REST,包从spring.jar拆分为按模块进行组织
  • 2.5 最低要求JDK 1.4.2,Servlet 2.3, JSP 1.2
========================================================================
十余年金融IT行业团队管理,系统架构,数据库架构与优化经验
擅长于大规模高并发j2ee soa体系系统架构设计与实现,精通j2ee系统性能分析与优化
精通oltp&dss oracle&mysql数据库设计、性能分析与优化、HA、分库分表应用架构设计与实现
我的开源项目io.spider,mysqlawr,logpool。https://git.oschina.net/zhjh256
来自:https://www.cnblogs.com/zhjh256/p/6118158.html

 


Servlet 3十二月2009开发平台标准版6,6可插性,易于开发,异步ser vlet,安全,文件上传
Servlet 2.5九月2005开发平台标准版5,5需要平台标准版5,支持注释
Servlet 2.4十一月2003中1.4,1.3 web.xml新解
Servlet 2.1十一月1998未正式规范,添加Dispatcher,Ser vlet Cont ext
Servlet 2类1.1部分程序开发工具包2
Servlet 1六月1997定义

j2ee标准-web.xml中load-on-startup源码解析

查看tomcat 7.0 源码:

/**
 * Load and initialize all servlets marked "load on startup" in the
 * web application deployment descriptor.
 *
 * @param children Array of wrappers for all currently defined
 *                 servlets (including those not declared load on startup)
 */
/**
 * StandardContext类,代表webapps目录下的一个web应用
 * 方法会被startInternal调用(),也就是应用在启动的时候
 * @param children
 * @return
 */
public boolean loadOnStartup(Container children[]) {

    // Collect "load on startup" servlets that need to be initialized
    //用TreeMap来排序 默认为natural order,也就是按ascii码
    TreeMap<Integer, ArrayList<Wrapper>> map =
            new TreeMap<Integer, ArrayList<Wrapper>>();
    for (int i = 0; i < children.length; i++) {
        Wrapper wrapper = (Wrapper) children[i];
        //每个Wrapper对应一个Servlet,负责创建、初始化、销毁servlet,并为其提供ServletConfig
        int loadOnStartup = wrapper.getLoadOnStartup();
        if (loadOnStartup < 0) //如果loadOnStartup的配置参数小于0,则不添加到TreeMap中
            continue;
        Integer key = Integer.valueOf(loadOnStartup);
        ArrayList<Wrapper> list = map.get(key);
        if (list == null) {
            list = new ArrayList<Wrapper>();
            map.put(key, list);
        }
        list.add(wrapper);
    }

    // Load the collected "load on startup" servlets
    //按loadOnStartup 的natural order即升序,依次对servlet进行初始化
    for (ArrayList<Wrapper> list : map.values()) {
        for (Wrapper wrapper : list) {
            try {
                //此方法包含对servlet的实例化和init方法的调用
                wrapper.load();
            } catch (ServletException e) {
                getLogger().error(sm.getString("standardContext.loadOnStartup.loadException",
                        getName(), wrapper.getName()), StandardWrapper.getRootCause(e));
                // NOTE: load errors (including a servlet that throws
                // UnavailableException from the init() method) are NOT
                // fatal to application startup
                // unless failCtxIfServletStartFails="true" is specified
                if (getComputedFailCtxIfServletStartFails()) {
                    return false;
                }
            }
        }
    }
    return true;

}

代码和清晰

总结:如果web.xml中的servlet没有配置 <load-on-startup> 标签或者其值小于0,那么在容器启动时不会对其初始化;否则按照数字升序排列串行对其初始化(这也证实了 正数的值越小,启动该servlet的优先级越高 这句话)。

来自:https://blog.csdn.net/joenqc/article/details/73497804


自己动手 单独测试了一下:

一、创建最新的dynamic web project
二、在WebContent目录中(即网站根目录),创建 index.jsp   如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>







<h3> helleo  word</h3>







</body>
</html>
三、编辑web.xml  文件 如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>webXml</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>S1</servlet-name>
    <servlet-class>com.web.servlet.S1</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>S2</servlet-name>
    <servlet-class>com.web.servlet.S2</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>S3</servlet-name>
    <servlet-class>com.web.servlet.S3</servlet-class>
    <load-on-startup>-1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>S4</servlet-name>
    <servlet-class>com.web.servlet.S4</servlet-class>
    <load-on-startup>4</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>S5</servlet-name>
    <servlet-class>com.web.servlet.S5</servlet-class>
    <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>S1</servlet-name>
    <url-pattern>/s1</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>S2</servlet-name>
    <url-pattern>/s2</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>S3</servlet-name>
    <url-pattern>/s3</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>S4</servlet-name>
    <url-pattern>/s4</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>S5</servlet-name>
    <url-pattern>/s5</url-pattern>
  </servlet-mapping>
</web-app>
四、创建 servlet 文件:

在 com.web.servlet 下面创建 5个 差不多的 servlet (eclipse 右键新建 servlet 即可) ,仅在 url ,构造函数 上进行了修改
S1 代码:

package com.web.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class S1
 */
@WebServlet(name = "S001", urlPatterns = { "/001" })
public class S1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public S1() {
        super();
        System.out.println("S1:init ready");
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

同理 S2代码如下:

package com.web.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class S1
 */
@WebServlet(name = "S002", urlPatterns = { "/002" })
public class S2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public S2() {
        super();
        System.out.println("S2:init ready");
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

其他servlet代码 类似

五、测试结果总结:

1、load on startup 大于等于 0,服务器启动时,会加载servlet ,并调用servlet的init方法。当以后 用 url 再访问 servlet时,servlet 不会再创建了,直接回把之前创建好的,直接拿过来用了。

@Override
public void init() throws ServletException {
	// TODO Auto-generated method stub
	super.init();
}

如果load on startup 值小于0,那么服务器启动时不会加载,直达 调用时才会 加载。加载完成后,以后调用时,就直接拿来用了,不会再创建第二遍了。

2、servlet 3.0 加入了注解功能,我上面写的S1。。。都用了注解。url 可以用/S1访问,也可以用 /001 访问。因为 同一个 servlet 配置时取了两个名字,两个路径。服务器 启动时,会当做两个 servlet 来处理,每种 url 访问都会创建一次。

j2ee标准-web.xml文件的含义

每个javaEE工程中都有web.xml文件,那么它的作用是什么呢?它是每个web.xml工程都必须的吗?

一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的。

web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。

当你的web工程没用到这些时,你可以不用web.xml文件来配置你的Application。

每个xml文件都有定义它书写规则的Schema文件,也就是说javaEE的定义web.xml所对应的xml Schema文件中定义了多少种标签元素,web.xml中就可以出现它所定义的标签元素,也就具备哪些特定的功能。web.xml的模式文件是由Sun 公司定义的,每个web.xml文件的根元素为<web-app>中,必须标明这个web.xml使用的是哪个模式文件。如:
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app version=”2.5″
xmlns=”http://java.sun.com/xml/ns/javaee”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd”>
</web-app>

web.xml的模式文件中定义的标签并不是定死的,模式文件也是可以改变的,一般来说,随着web.mxl模式文件的版本升级,里面定义的功能会越来越复杂,标签元素的种类肯定也会越来越多,但有些不是很常用的,我们只需记住一些常用的并知道怎么配置就可以了。

下面列出web.xml我们常用的一些标签元素及其功能:

1、指定欢迎页面,例如:
<welcome-file-list>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index1.jsp</welcome-file>
</welcome-file-list>
PS:指定了2个欢迎页面,显示时按顺序从第一个找起,如果第一个存在,就显示第一个,后面的不起作用。如果第一个不存在,就找第二个,以此类推。

关于欢迎页面:

访问一个网站时,默认看到的第一个页面就叫欢迎页,一般情况下是由首页来充当欢迎页的。一般情况下,我们会在web.xml中指定欢迎页。但 web.xml并不是一个Web的必要文件,没有web.xml,网站仍然是可以正常工作的。只不过网站的功能复杂起来后,web.xml的确有非常大用处,所以,默认创建的动态web工程在WEB-INF文件夹下面都有一个web.xml文件。

2、命名与定制URL。我们可以为Servlet和JSP文件命名并定制URL,其中定制URL是依赖命名的,命名必须在定制URL前。下面拿serlet来举例:
(1)、为Servlet命名:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.whatisjava.TestServlet</servlet-class>
</servlet>

(2)、为Servlet定制URL、
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

3、定制初始化参数:可以定制servlet、JSP、Context的初始化参数,然后可以再servlet、JSP、Context中获取这些参数值。

下面用servlet来举例:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.whatisjava.TestServlet</servlet-class>
<init-param>
<param-name>userName</param-name>
<param-value>Daniel</param-value>
</init-param>
<init-param>
<param-name>E-mail</param-name>
<param-value>[email protected]</param-value>
</init-param>
</servlet>
经过上面的配置,在servlet中能够调用getServletConfig().getInitParameter(“param1”)获得参数名对应的值。

4、指定错误处理页面,可以通过“异常类型”或“错误码”来指定错误处理页面。
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
—————————–
<error-page>
<exception-type>java.lang.Exception<exception-type>
<location>/exception.jsp<location>
</error-page>

5、设置过滤器:比如设置一个编码过滤器,过滤所有资源
<filter>
<filter-name>XXXCharaSetFilter</filter-name>
<filter-class>net.test.CharSetFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XXXCharaSetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

6、设置监听器:
<listener>
<listener-class>net.test.XXXLisenet</listener-class>
</listener>

7、设置会话(Session)过期时间,其中时间以分钟为单位,假如设置60分钟超时:
<session-config>
<session-timeout>60</session-timeout>
</session-config>

除了这些标签元素之外,还可以往web.xml中添加很多标签元素,由于不常用省略。

来自:https://www.cnblogs.com/yqskj/articles/2233061.html

j2ee标准-web-inf文件夹的意义

写这篇文章的原因是看到了Tomcat下面的Webapps下面的,就想看一下。

总结一下这篇文章的内容:

WEB-INF下面的内容都是只能由服务器级别才能访问,客户端并不能访问。什么是客户端级别?什么是服务器级别呢?

转发就是服务器级别,浏览器的地址不会变,因为,客户端发送一个请求,服务器受理之后,发现要请求内容还要再去别的请求,那么转发就是服务器自己去处理完成。不麻烦客户端(浏览器)了,所以客户端上面的地址栏不会改变。

重定向:就是客户端级别的。服务器收到请求后,发现还要去请求别的内容,但是服务器自己不想处理,那么就告诉客户端,你自己去处理吧,那么客户端就去请求那个别的内容了。所以客户端(浏览器)地址栏就会改变了。


在web项目中,为了安全,可能需要把jsp文件放在WEB-INF目录下,这样如果我们的页面中出现超链接a标签或者js的location.href去直接转向到WEB-INF下的某一个jsp页面,那么就会引用不到,因为这样的请求方式是客户端的请求,而WEB-INF页面只对服务端开放,对客户端是不可见的。这时候我们可以使用action,来进行转向,我们先去请求一个action,然后由这个action分发到这个WEB-INF下的页面就可以了。我们可以自己定义一个类似struts1的DispatcherAction的一个action来分发页面。

由于WEB-INF下对客户端是不可见的,所以相关的资源文件,如css,javascript和图片等资源文件不能放在WEB-INF下,那么如何从WEB-INF下引用非WEB-INF下的文件,以及js,html的frame的框架如何去访问WEB-INF下的jsp呢?

下面对WEB-INF目录的一些问题进行详细说明:

以一个项目为例:

如下这样一个代码目录:我们把除index.jsp外其他的jsp文件放在WEB-INF下,把css,javascript,图片放在了webRoot(WebContent)目录下,然后main.jsp是一个frame的html框架,包含了main1.jsp和main2.jsp两个文件。

1、index.jsp页面访问css,js,图片等文件的时候,自然不用说,因为它不在WEB-INF下,正常的访问即可:

<link href="css/login_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/login_js.js"></script>

<img alt="" src="image/1.jpg">

2、register.jsp页面去访问css,js和图片的时候,也是不需要添加WEB-INF目录的,也就是忽略WEB-INF目录,访问的时候和index.jsp页面所在的路径访问资源文件是一样的:

<link href="css/register_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/register_js.js"></script>

<img alt="" src="image/2.jpg">

3、register.jsp页面去转向index.jsp页面,即注册页面有一个链接,转向到登录界面,由于index.jsp页面没有在WEB-INF下,所以可以直接访问index.jsp页面的路径,

 register.jsp:

<tr>

    <td></td>

    <td colspan="2" style="float: left; ">

        <button type="button" >注册</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

        <button type="button"  onclick="goLogin()">去登录</button>

    </td>

</tr>

在register.jsp页面中定义了一个botton,然后响应一个onclick事件,

我们在register_js.js中定义这个goRegister ()的js事件:

regitster_js.js:

function goLogin(){

    location.href="index.jsp";

}

这样就可以访问到WebContent目录中的index.jsp页面了。

 

4、index.jsp(登录页面)有一个链接,指向register页面,如果点击链接,就跳转到register.jsp中进行注册,因为register.jsp在WEB-INF下,所以不可以直接使用a标签去访问WEB-INF路径下的文件:

<a href="WEB-INF/register/register.jsp">去注册</a>

或者js的location.href去访问:

function goRegister(){  

    location.href="WEB-INF/register/register.jsp";

}

这样两种方式都是直接请求了WEB-INF路径,都是无法跳转的。

我们可以建立一个action,struts的action中没有DispatcherAction,但是我们可以通过通配符来让一个action的不同方法返回不同的页面,然后我们去请求这个action中的相应方法即可由这个action从服务器端请求到WEB-INF下的页面了:

下面详细说明如果进行自定义的分发action来进行页面的分发:

DispatcherAction.java:

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;
publicclass DispatcherAction extends ActionSupport{
    public String goRegister(){

        return"goRegister";

    }
}

这个action中,我们定义了一个goRegister的方法,这个方法没有任何逻辑代码,只是返回一个字符串,然后在struts.xml中我们让这个字符串指向我们要访问的WEB-INF下的register.jsp页面:

struts.xml:

<action name ="dispatcher" class="com.yun.test.webinf.action.DispatcherAction" >

    <result name ="goRegister">WEB-INF/register/register.jsp</result >

    <result name ="input">/index.jsp</result >

</action >

然后我们可以在页面中进行请求DispatcherAction的goRegister方法,然后这个action的goRegister方法就会把页面转向到WEB-INF下的register.jsp页面了:

我们在index.jsp中定义了一个botton,然后给这个botton注册一个点击事件:

index.jsp:

<tr>

    <td></td>

    <td colspan="2" style="float: left; ">

        <button onclick="checkValues()">登录</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

        <button type="button" id="button1" onclick="goRegister()">去注册</button>

    </td>

</tr>

在index_js.js中定义这个点击事件为location.href到定义的action的goRegister.action方法中:

login_js.js:

function goRegister(){

    location.href="dispatcher!goRegister.action";

}

当然,也可以直接在页面中使用a标签来请求这个action的goRegister方法:

    <a href="dispatcher!goRegister.action">去注册</a>

这样我们就可以通过action的转发,成功的请求道WEB-INF下的jsp文件了。

注意请求action的方式,dispatcher!goRegister.action  这个!是一个分发字符,!之前的部分是action的名字,!之后的部分是这个action的某个我们要请求的方法的名字。然后这个action中必须要定义一个同名的方法,就不需要使用execute方法了。然后这个同名方法,返回的是一个String字符串,这个字符串在struts.xml中指向为我们想要跳转的路径。这就是一个请求分发的action。

我们还可以自己定义分发的分隔符,可以是下划线等,分发action详见Struts2实现分发的action一节

5、jsp页面中的frame框架中想把多个WEB-INF下的页面设置为框架的内容的时候,即使main.jsp和main1.jsp,main2.jsp同在WEB-INF目录下,也不可以直接去指定WEB-INF路径,如:

<frameset cols="30%,70%">

    <frame src="main/main1.jsp">

    <frame src="main/main1.jsp">

</frameset>

这样还是不能访问,也必须使用服务端的action分发的方式进行指定jsp文件的路径。

代码如下:

main.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>main</title>
</head>
<frameset cols="30%,70%">

    <frame src="dispatcher!goMain1.action">

    <frame src="dispatcher!goMain2.action">

</frameset>
</html>

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    

<struts >

    <package name ="test" extends ="struts-default" >

        <action name ="dispatcher" class ="com.yun.test.webinf.action.DispatcherAction" >

            <result name ="goRegister">WEB-INF/register/register.jsp</result >

            <result name ="goMain1">WEB-INF/main/main1.jsp</result >

            <result name ="goMain2">WEB-INF/main/main2.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="login" class ="com.yun.test.webinf.action.LoginAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="register" class ="com.yun.test.webinf.action.RegisterAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">WEB-INF/register/register.jsp</result >

        </action >
  </package>
<!-- 定义struts标签为无默认样式 -->

    <constant name="struts.ui.theme" value="simple" />

</struts>

DispatcherAction.java:

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;

publicclass DispatcherAction extends ActionSupport{
    public String goRegister(){
        return"goRegister";

    }

    public String goMain1(){
        return"goMain1";
    }

    public String goMain2(){

        return"goMain2";

    }
}

这样,这个main页面就可以通过action分发使用frame框架了。

 

6、同在WEB-INF目录下的register.jsp和main.jsp中怎么跳转呢?我们会在register.jsp中提交表单,然后在action中进行处理,如果注册成功,会跳转到main页面,这时的跳转也会涉及到WEB-INF目录,因为目标路径main.jsp也在WEB-INF下,所以我们在跳转的时候也必须写上WEB-INF的目录路径才可以,而且必须是请求分发,而不能是redirct的方式。

如代码:

register.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>register</title>

<link href="css/register_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/register_js.js"></script>

</head>

<body>
    <div id="content" >

    <form action="register.action" id="registerForm"  method="post">
        <table>

            <tr>

                <td width="150px;" style="text-align:center; ">注册名</td>

                <td width="80px;" style="text-align: left;"><input type="text" name="user.username"  id="username" ></td>

                <td width="400px;" style="text-align: left;"><font color="red">* 请输入用户名</font></td>

            </tr>

            <tr>

                <td width="100px;" style="text-align:center; ">注册密码</td>

                <td width="80px;" style="text-align: left;"><input type="password" name="user.password" size="22" id="password"></td>

                <td width="400px;" style="text-align: left;"><font color="red">* 请输入密码</font></td>

            </tr>

            <tr>

                <td></td>

                <td colspan="2" style="float: left; ">

                    <button type="button"  onclick="checkValues()">注册</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

                    <button type="button"  onclick="goLogin()">去登录</button>

                </td>

            </tr>

        </table>

 

     </form>

    </div>

    <img alt="" src="image/2.jpg">

</body>

</html>

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts >

    <package name ="test" extends ="struts-default" >

        <action name ="dispatcher" class ="com.yun.test.webinf.action.DispatcherAction" >

            <result name ="goRegister">WEB-INF/register/register.jsp</result >

            <result name ="goMain1">WEB-INF/main/main1.jsp</result >

            <result name ="goMain2">WEB-INF/main/main2.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="login" class ="com.yun.test.webinf.action.LoginAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="register" class ="com.yun.test.webinf.action.RegisterAction" >

            <result name ="success">WEB-INF/main.jsp</result >

           <result name ="input">WEB-INF/register/register.jsp</result >

        </action >

 

    </package>

 

    <!-- 定义struts标签为无默认样式 -->

    <constant name="struts.ui.theme" value="simple" />

</struts>

RegisterAction.java:

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;

import com.yun.test.webinf.entity.User;
public class RegisterAction extends ActionSupport{
         private User user;
         public void setUser(User user) {
                   this.user = user;

         }

         public User getUser() {
                   return user;

         }

         @Override

         public String execute() throws Exception {

                   if("lisi".equals(user.getUsername())&&"lisi".equals(user.getPassword())){

                            return SUCCESS;

                   }

                   return INPUT;

         }

         

}

 

接下来对WEB-INF页面中的注意事项进行说明:

1、把页面资源文件只能放在WebContent目录内,,如CSS,JS,image等.不能放在WEB-INF下,因为WEB-INF是对客户端隐藏的,所以放在WEB-INF下会造成页面的布局等文件引用不到的情况。
2、页面文件一般放在WEB-INF目录下面,这样可以限制访问,提高安全性.如JSP,html文件,放在WEB-INF目录下就可以避免客户端直接在地址栏上输入路径进行访问了。基于不同的功能,把JSP 放置在WEB-INF下的不同的目录中。
3、只能用转向方式来访问WEB-INF目录下的JSP,不用采用重定向的方式请求该目录里面的任何资源。
4、转向方式:

4.1、请求转发:

如struts.xml文件中配置

<result name ="goMain2">WEB-INF/main/main2.jsp</result >

或在Action中写

request.getRequestDispatcher(“/WEB-INF/main/main2.jsp”).forward(request, response);

的方式都是服务器读取了该页面内容,并发送到客户端的,客户端的地址不变,然后内容跳转了。这样的方式是可以访问到WEB-INF目录下的jsp文件的。

4.2、重定向方式:

如struts.xml文件中配置

<result name ="goMain2" type="redirect">WEB-INF/main/main2.jsp</result >

 或在action中

response.sendRedirect(“WEB-INF/main/main2.jsp “);

都属于重定向的方式,重定向的含义就是服务器把地址发给客户端,让客户端去访问,这样还是在客户端访问的WEB-INF目录,所以是无法访问到WEB-INF目录下的jsp文件的。

5、有一些标签,也是可以访问到WEB-INF目录中的文件的,如果符合要求的情况下也可以使用,如:

<jsp:forward page = "/WEB-INF/jsp/test/test.jsp" />

<a href="javascript:<jsp:forward page='WEB-INF/xxxx.jsp'/>"></a>

<jsp:include page="WEB-INF/xxx.jsp">

都是可以访问WEB-INF下的jsp文件的。但是局限性很大,还是建议使用action分发的方式。

来自:https://www.cnblogs.com/shenxiaoquan/p/5819359.html

j2ee标准-j2ee简介

人们平常说的Java一般指JavaSE,也就是Java Standard Edition,Java的标准版,一般用来开发桌面应用程序,但是在开发桌面应用程序上相对VB,Delphi,VC++并没有什么优势。

而JavaWeb则到了JavaEE(J2EE)领域了,也就是Java Enterprise Edition,Java的企业版,看那个web就应该想到是与Internet有关的,其实开发JavaWeb应用程序,初级的一般是用JSP(Java Server Pages)+servlet+Javabean来开发的,对大型的网站一般是使用框架来开发的,例如struts,hibernate,spring,例如校内,你在登陆的时候会在地址栏看见Login.do,登陆以后会看见Home.do这样的请求,典型的struts框架结构。

J2EE核心是一组技术规范与指南,其中所包含的各类组件、服务架构及技术层次,均有共同的标准及规格,让各种依循J2EE架构的不同平台之间,存在良好的兼容性,解决过去企业后端使用的信息产品彼此之间无法兼容,企业内部或外部难以互通的窘境。

Java还有一个版本是JavaME,Java Micro Edition,Java的微型版,诺基亚手机上运行的Java程序就是指用这个版本开发的程序。