servlet系列-Tomcat、webapp、servlet初步

2017-11-15 11:37:33来源:segmentfault作者:菟潞寺沙弥人点击

分享
关于服务器
WebServer & Application Server

Q: What is the difference between an application server and a Web server?


A:



Web server exclusively handles HTTP requests, whereas an application server serves business logic to application programs through any number of protocols.


The Web server

https://www.javaworld.com/art...


Web server handles the HTTP protocol. When the Web server receives an HTTP request, it responds with an HTTP response, such as sending back an HTML page. To process a request, a Web server may respond with a static HTML page or image, send a redirect, or delegate the dynamic response generation to some other program such as CGI scripts, JSPs (JavaServer Pages), servlets, ASPs (Active Server Pages), server-side JavaScripts, or some other server-side technology. Whatever their purpose, such server-side programs generate a response, most often in HTML, for viewing in a Web browser.


Understand that a Web server's delegation model is fairly simple. When a request comes into the Web server, the Web server simply passes the request to the program best able to handle it. The Web server doesn't provide any functionality beyond simply providing an environment in which the server-side program can execute and pass back the generated responses. The server-side program usually provides for itself such functions as transaction processing, database connectivity, and messaging.


While a Web server may not itself support transactions or database connection pooling, it may employ various strategies for fault tolerance and scalability such as load balancing, caching, and clustering—features oftentimes erroneously assigned as features reserved only for application servers.


The application server

As for the application server, according to our definition, an application server exposes business logic to client applications through various protocols, possibly including HTTP. While a Web server mainly deals with sending HTML for display in a Web browser, an application server provides access to business logic for use by client application programs. The application program can use this logic just as it would call a method on an object (or a function in the procedural world).


Such application server clients can include GUIs (graphical user interface) running on a PC, a Web server, or even other application servers. The information traveling back and forth between an application server and its client is not restricted to simple display markup. Instead, the information is program logic. Since the logic takes the form of data and method calls and not static HTML, the client can employ the exposed business logic however it wants.


In most cases, the server exposes this business logic through a component API, such as the EJB (Enterprise JavaBean) component model found on J2EE (Java 2 Platform, Enterprise Edition) application servers. Moreover, the application server manages its own resources. Such gate-keeping duties include security, transaction processing, resource pooling, and messaging. Like a Web server, an application server may also employ various scalability and fault-tolerance techniques.


servlet
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
插播一段maven scope的知识

compile (编译范围)


compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。


provided (已提供范围)


provided 依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。


runtime (运行时范围)


runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC
驱动实现。


test (测试范围)


test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。


system (系统范围)


system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)。


http://blog.csdn.net/yhao2014...
https://qiita.com/Dog404/item...
http://blog.csdn.net/wangxiao...
http://www.jianshu.com/p/0e53...


java代码

继承HttpServlet类


@WebServlet("/helloworld")
public class HelloWorld extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<h1>Hello world</h1>");
}
}

如果不使用注解@WebServlet,需要配置web.xml


<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>com.meituan.servlet.HelloWorld</servlet-class>
</servlet><servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>

其他两种servlet实现方式


实现javax.servlet.Servlet;


@WebServlet("/helloworld")
public class HelloWorld implements Servlet{
public void init(ServletConfig config) throws ServletException {}public ServletConfig getServletConfig() {
return null;
}public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("实现servlet接口");
}public String getServletInfo() {
return null;
}public void destroy() {}
}

继承GenericServlet


@WebServlet("/helloworld")
public class HelloWorld extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("继承GenericServlet");
}
}
servlet乱码解决方式

原博:http://blog.csdn.net/xiazdong...


常识

GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立;


java.nio.charset.Charset.defaultCharset() 获得平台默认字符编码;


getBytes() 是通过平台默认字符集进行编码;

中文乱码出现


在学习任何一门技术时,经常会有初学者遇到中文乱码问题,比如MySQL,是因为在安装时没有设置;而在Servlet中,也会遇到中文乱码问题;
比如:
OutputStream out = response.getOutputStream();
out.write(String );
输出中文时可能会出现乱码;
比如:


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {OutputStream out = response.getOutputStream();
String data = "博客";
out.write(data.getBytes("UTF-8"));
}

输出乱码的问题是程序用UTF-8编码,而浏览器用GB2312解码,因此会出现乱码;
Servlet乱码分为request乱码和response乱码;


response中文乱码


在网上很有效的解决方法是添加:
response.setCharacterEncoding("UTF-8");
解决不了,后来又搜到一条解决方法是:
respnse.setHeader("content-type","text/html;charset=UTF-8");
两句都填上,后来终于解决了这个问题;
其实我们应该思考一下本质;


问题1:

我们这里先来说明一下错误的原因,下图是显示乱码的流程图:



response.setContentType("text/html;charset=UTF-8"); 目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码;
response.setCharacterEncoding("UTF-8"); 的目的是用于response.getWriter()输出的字符流的乱码问题,如果是response.getOutputStream()是不需要此种解决方案的;因为这句话的意思是为了将response对象中的数据以UTF-8解码后发向浏览器;


解决方案流程图:



问题2:

问题代码如下:


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String data = "博客";
out.println(data);
}

浏览器输出: ??
原因:"博客"首先被封装在response对象中,因为IE和WEB服务器之间不能传输文本,然后就通过ISO-8859-1进行编码,但是ISO-8859-1中没有“博客”的编码,因此输出“??”表示没有编码;


错误代码流程图:



而解决方案是:response.setCharacterEncoding("GB2312"); 设置response使用的码表


解决方案流程图:



补充:通过<meta>标签模拟response头;


<meta http-equiv="content-type" content="text/html"/> 等价于 response.setContentType("text/html");


request乱码问题


request请求分为post和get,对于不同的请求方式有不同的解决乱码的方案;


1.post请求乱码



解决方案:



2.get请求乱码


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台