[toc]
Servlet簡單的介紹
Servlet是sun公司提供的一門用于開發(fā)動(dòng)態(tài)web資源的技術(shù)漱贱。
Sun公司在其API中提供了一個(gè)servlet接口,用戶若想用發(fā)一個(gè)動(dòng)態(tài)web資源(即開發(fā)一個(gè)Java程序向?yàn)g覽器輸出數(shù)據(jù))陨亡,需要完成以下2個(gè)步驟:
1. 編寫一個(gè)Java類,實(shí)現(xiàn)servlet接口农尖。
2. 把開發(fā)好的Java類部署到web服務(wù)器中涣易。
按照一種約定俗成的稱呼習(xí)慣,通常我們也把實(shí)現(xiàn)了servlet接口的java程序焊刹,稱之為Servlet
Servlet與SpringMVC關(guān)系
SpringMVC是基于Servlet封裝的MVC框架
建立傳統(tǒng)web項(xiàng)目
1. 選擇webapp
2.創(chuàng)建的mavenweb工廠 發(fā)現(xiàn)沒有java目錄系任,則創(chuàng)建java目錄
3. 相關(guān)Servlet配置信息
1)基于XML方式
定義一個(gè)servlet類
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print(" this is MyServlet");
}
}
在web.xml中加入配置
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.xxx.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2)基于注解方式
@WebServlet("/")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print(" this is MyServlet");
}
}
4. ServletContainerInitializert配置
定義基類HandleType(SpringMVC默認(rèn)使用WebApplicationInitializer)
public class MyHandlesType {
}
定義子類HandleType
public class SpringHandlesType extends MyHandlesType {
}
定義子類HandleType
public class PayHandlesType extends MyHandlesType {
}
Servlet初始化類(SpringMVC默認(rèn)使用SpringServletContainerInitializer)
@HandlesTypes(value = MyHandlesType.class)
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* @param set 獲取到所有繼承MyHandlesType所有子類型(也就是感興趣類型)
* @param servletContext
* @throws ServletException
*/
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
// 1.打印所有感興趣的類型
for (Class<?> c : set) {
System.out.println(c);
}
// 2.servletContext 手動(dòng)注冊過濾器、servlet虐块、監(jiān)聽器
// PayServlet為HttpServlet實(shí)現(xiàn)類
ServletRegistration.Dynamic payServlet = servletContext.addServlet("payServlet", new PayServlet());
payServlet.addMapping("/pay");
}
}
5. 指定ServletContainerInitializer
- 創(chuàng)建META-INF/services 目錄
- 在META-INF/services 目錄創(chuàng)建文件javax.servlet.ServletContainerInitializer
- javax.servlet.ServletContainerInitializer文件內(nèi)容指定MyServletContainerInitializer包名+類名(例如:com.xxx.config.MyServletContainerInitializer)
建立無配置文件web項(xiàng)目
不需要定義自定HandleType俩滥、ServletContainerInitializer 和 HttpServlet實(shí)現(xiàn)類,因?yàn)閟pring-web的Jar中已經(jīng)定義了贺奠,只需要讓ServletContainerInitializer加載mvc配置霜旧、web配置,實(shí)現(xiàn)的方法就是
1)定義SpringMVC配置
@Configuration
@EnableWebMvc
@ComponentScan("com.xxx.controller")
public class MyMvcConfig {
// @Configuration 當(dāng)前類屬于配置類儡率,相當(dāng)于XML
// @EnableWebMvc 開啟SpringMVC注解方式
// @ComponentScan 指定掃包范圍
}
2)定義web服務(wù)配置颁糟,代替web.xml
public class WebInitializer implements WebApplicationInitializer {
public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
// 1. 創(chuàng)建SpringMVC容器
AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
// 2. 注冊我們的配置文件
app.register(MyMvcConfig.class);
// 注冊我們的
DispatcherServlet dispatcherServlet = new DispatcherServlet(app);
ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcherServlet", dispatcherServlet);
dynamic.addMapping("/");
// 最優(yōu)先啟動(dòng)
dynamic.setLoadOnStartup(1);
}
}
注意事項(xiàng)
問題1
注意:Servlet是單例的,是線程不安全的喉悴,每次請求到服務(wù)器中不會(huì)重新創(chuàng)建servlet實(shí)例。
@WebServlet("/")
public class MyServlet extends HttpServlet {
private Integer count = 0;
public MyServlet() {
System.out.println("<<<MyServlet被實(shí)例化...>>>");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
count++;
try {
Thread.sleep(50);
} catch (Exception e) {
}
resp.getWriter().print(" this is MyServlet count:" + count);
}
}
訪問三次服務(wù)玖媚,輸出的結(jié)果:
.......
<<<MyServlet被實(shí)例化...>>>
.......
this is MyServlet count:1
this is MyServlet count:2
this is MyServlet count:3
問題2
ServletContainerInitializer
- 在web容器啟動(dòng)時(shí)為提供給第三方組件機(jī)會(huì)做一些初始化的工作箕肃,例如注冊servlet或者filtes等,servlet規(guī)范中通過ServletContainerInitializer實(shí)現(xiàn)此功能今魔。
- 每個(gè)框架要使用ServletContainerInitializer就必須在對應(yīng)的jar包的META-INF/services 目錄創(chuàng)建一個(gè)名為javax.servlet.ServletContainerInitializer的文件勺像,文件內(nèi)容指定具體的ServletContainerInitializer實(shí)現(xiàn)類障贸。
- Servlet容器啟動(dòng)會(huì)掃描,當(dāng)前應(yīng)用里面每一個(gè)jar包的ServletContainerInitializer的實(shí)現(xiàn)
來源:螞蟻課堂