Compilation software: IntelliJ IDEA 2019.2.4 x64
Operating system: win10 x64-bit Home Edition
Server software: apache-tomcat-8.5.27
Table of contents
- 1. What is a Servlet?
- 2. How to write the first servlet program?
- 3. Servlet life cycle
- Four. Servlet technical system
- Five. Two interfaces in the web project
- 6. Interface for processing requests and responses
- 7. Processing of request and response garbled characters
- 8. Case: login and registration function of connection database version
- Nine. Use Beanutils to optimize code
- 10. The path problem of the web project★
1. What is a Servlet?
Servlet,英文全称为Server Applet,意为服务器端的一小程序
. It runs on a web server that supports the Java Servlet specification. Among the many web applications deployed on the server, no matter it is a B/S architecture or a C/S architecture, their basic operation mode is shown in the following figure (taking Java programs as an example):
If the operation mode of the above-mentioned web application is compared to a restaurant that is in business, then the Servlet plays the role of the waiter in it . When the customer enters the restaurant to eat ( the client sends a request ), it is responsible for serving the menu to the customer and waiting for the customer to order. For the menu, the servlet will notify the cook ( web application ) to cook (handle the business), and the cook will ask the waiter to serve the dishes ( response ) to the guests.
总的来说,Servlet就是和客户端进行交互(处理请求和响应)
Servlets are commonly used to create web applications like e-commerce sites, social media applications, online banking sites, and the like. By using Servlets, developers can build web applications in a portable, flexible, efficient and reusable manner.
2. How to write the first servlet program?
step:
①Create an html page and create a hyperlink on it (plan to visit the HelloServlet in the background)
<a href="">访问HelloServlet</a>
②Create HelloServlet
- Create a new common class HelloServelet
- HelloServlet implements interface Servlet
- Implement all abstract methods in the interface
The code demonstration is as follows:
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 主要功能:处理客户端的请求和响应
* @param servletRequest 处理请求
* @param servletResponse 处理响应
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("访问了HelloServlet类的service方法.......");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
- Set the access path for HelloServlet in web.xml
The code demonstration is as follows:
<!-- HelloServlet的访问路径:/hello -->
<servlet>
<!-- 为Servlet起个名字 -->
<servlet-name>abc</servlet-name>
<!-- Servlet的全类名 -->
<servlet-class>t1.HelloServelet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 要和Servlet中的servlet-name的名字一致 -->
<servlet-name>abc</servlet-name>
<!-- 设置访问路径,注意,必须是/开头 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
③Set the set access path to the hyperlink
<a href="hello">访问HelloServlet</a>
④Test HelloServlet
Notice:
网页必须直接在web下(不能放在WEB-INF下)
web.xml中url-pattern的值必须以/开头
- The request path of the webpage, which cannot start with /
- Web pages cannot be opened in a static way
The request principle is as follows:
Servlet object management:
-
Servlet的实例对象由Servlet容器(tomcat)负责创建
-
Servlet的方法由容器在特定情况下调用
-
Servlet容器会在web应用卸载时(tomcat停止)销毁Servlet对象的实例
3. Servlet life cycle
There are five methods in the Servlet interface, three of which are related to the life cycle (init/service/destroy).
Request process:
默认情况下在第一次发出请求时,Servlet容器(tomcat服务器)会创建相应的servlet对象、进行初始化(执行init方法)、执行service方法
第二次以及以后的每一次请求发出,都直接执行service方法
在web应用被卸载(服务器被停止时)的时候,servlet对象会被销毁,销毁之前执行destroy方法
Can a servlet create its object when starting the server?
Can
Methods as below:
Add a tag inside the servlet tag of the current Servlet in web-xml
//设置自启动
<load-on-startup>l</1oad-on-startup>
The code demonstration is as follows:
<!-- 设置自启动,若有多个servlet都设了自启动,根据标签体中的值来判定启动优先级,值越小,优先级越高 -->
<!-- <load-on-startup></load-on-startup>中的标签体为非0的整数 -->
<load-on-startup>1</load-on-startup>
Four. Servlet technical system
Three ways to create a Servlet:
① Implement the Servlet interface
Rewrite its five methods (only one service is the focus), and the other four must also be rewritten
Case: Create a HelloServlet class to implement the Servlet interface
The code demonstration is as follows:
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 主要功能:处理客户端的请求和响应
* @param servletRequest 处理请求
* @param servletResponse 处理响应
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("访问了HelloServlet类的service方法.......");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
web-xml creates its access path:
<!-- HelloServlet的访问路径:/hello -->
<servlet>
<!-- 为Servlet起个名字 -->
<servlet-name>abc</servlet-name>
<!-- Servlet的全类名 -->
<servlet-class>t1.HelloServelet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 要和Servlet中的servlet-name的名字一致 -->
<servlet-name>abc</servlet-name>
<!-- 设置访问路径,注意,必须是/开头 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
②Inherit GenericServlet
step:
- create a class
- Inherit an abstract class (GenericServlet)
- Implement an abstract method in an abstract class
- Configure the access path of Servlet in web-xml
Notice:
The main function of GenericServlet is to implement the four methods other than service. Our own Servlet only needs to implement the service method . If you want to use the other four methods, you can use rewriting.
Case: Create MyFirstServlet class to inherit GenericServlet class
The code demonstration is as follows:
public class MyFirstServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("触发了继承GenericServlet类的子类MyFirstServlet类的service方法......");
}
}
web-xm configures its access path:
<!-- 设置访问MyFirstServlet的路径:/myfirst -->
<servlet>
<servlet-name>def</servlet-name>
<servlet-class>t1.MyFirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>def</servlet-name>
<url-pattern>/myfirst</url-pattern>
</servlet-mapping>
③ Inherit HttpServlet
step:
-
create a class
-
Inherit an abstract class (HttpServlet)
-
Override two methods doGet and doPost
-
Configure the access path of the Servlet
Notice:
The main function of HttpServlet is to implement the service method, and then distribute the request (different request methods call different methods). The get request calls the doGet method , and the post request calls the doPost method .
Case: Create MyFirstServlet class to inherit GenericServlet class
The code demonstration is as follows:
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecondServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("访问了SecondServlet里的doPost方法");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("访问了SecondServlet里的doGet方法");
}
}
web-xm configures its access path:
<!-- 设置访问SecondServlet的路径:/second -->
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>t1.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/second</url-pattern>
</servlet-mapping>
Five. Two interfaces in the web project
5.1 Servletconfig interface
A Servlet object corresponds to a unique ServletConfigi configuration object
How to get Servletconfig object?
In the formal parameter position of the init method, Servletconfig is passed to the init method when the current Servlet is initialized
The main function:
-
Get the Servlet name (the value of servlet-name in web.xml)
//获取Servlet名称 String servletName = servletConfig.getServletName(); System.out.println("servletName:"+servletName);
-
Get the global context (ServletContext) object
//获取全局上下文对象 ServletContext servletContext = servletConfig.getServletContext(); System.out.println("servletContext:"+servletContext);
-
Get Servlet initialization parameters
The prerequisite for obtaining Servlet initialization parameters is to have servlet initialization parameters
How to set the initialization parameters of the servlet?
Location: In the servlet tag of web.xml, set above sub-tag 1–>, otherwise an error will be reported
The code demonstration is as follows:
<!--设置当前Servlet的初始化参数--> <init-param> <param-name>path</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param>
Get Servlet initialization parameters:
//获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值 String path = servletConfig.getInitParameter("path"); System.out.println("path:"+path); //获取HelloServelet内所有初始化参数的<param-name>【key】值 Enumeration<String> initParameterNames = servletConfig.getInitParameterNames(); while (initParameterNames.hasMoreElements()){ System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement()); }
Case: Implement the above functions in the HelloServelet class
The code demonstration is as follows:
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
public HelloServelet() {
System.out.println("HelloServelet类的构造方法被执行了");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("HelloServelet类的init方法被执行了");
//1.获取的是当前Servlet名称(web.xml中配置servlet-name的值)
String servletName = servletConfig.getServletName();
System.out.println("servletName:"+servletName);
//2.获取全局上下文ServletContext对象
ServletContext servletContext = servletConfig.getServletContext();
System.out.println("servletContext:"+servletContext);
//3.获取Servlet初始化参数
//获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值
String path = servletConfig.getInitParameter("path");
System.out.println("path:"+path);
//获取web-xml中的初始化参数<param-name>为aaa的value值
String aaa = servletConfig.getInitParameter("aaa");
System.out.println("aaa:"+aaa);
//获取HelloServelet内所有初始化参数的<param-name>【key】值
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement());
}
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 主要功能:处理客户端的请求和响应
* @param servletRequest 处理请求
* @param servletResponse 处理响应
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("访问了HelloServlet类的service方法.......");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("HelloServelet类的destroy方法被执行了");
}
}
5.2 ServletContext interface
Notice:
- A web project has only one ServletContext object, representing the current web application
- All Servlets share the same ServletContext object, so the ServletContext object is also called the application object (Web application object)
- The ServletContext object is created by Tomcat when the server is started, and destroyed when the project is unloaded (when the server is shut down).
How to get the ServletContext object?
-
Get it through ServletConfig
//使用servletConfig获取全局上下文ServletContext对象 ServletContext servletContext = servletConfig.getServletContext(); System.out.println("servletContext:"+servletContext);
-
Get it through request
//使用servletRequest获取servletcontext对象(全局上下文对象) ServletContext servletContext = servletRequest.getServletContext(); System.out.println("servletContext:"+servletContext);
The main function:
-
Get the context path of the project (project name with "/")
//1.获取项目的上下文路径(带/的项目名) String contextPath = servletContext.getContextPath(); System.out.println("contextPath:"+contextPath);
-
Get the local real path mapped by the virtual path
Purpose: Need to use when uploading or downloading files
//2.获取虚拟路径所映射的本地真实路径(根据相对路径获得绝对路径) String realPath = servletContext.getRealPath("/upload"); System.out.println("realPath:"+realPath);
-
Get the global initialization parameters of the WEB application
The prerequisite for obtaining global initialization parameters is that you must have global initialization parameters, if not, you must set them
How to set global initialization parameters?
Location: On the root node of web.xml
The corresponding code on web.xml looks like this:
<context-param> <param-name>context-key</param-name> <param-value>context-value</param-value> </context-param> <context-param> <param-name>ccc</param-name> <param-value>ddd</param-value> </context-param>
//3.获取WEB应用程序的全局初始化参数 //获取全局初始化参数中<param-name>【 key】为ccc的value值 String ccc = servletContext.getInitParameter("ccc"); System.out.println("ccc="+ccc); //获取全局初始化参数中<param-name>【 context-key】为ccc的value值 String context_key = servletContext.getInitParameter("context-key"); System.out.println("context_key="+context_key); //获取全局初始化参数中所有的<param-name>【 key】值 Enumeration<String> initParameterNames = servletContext.getInitParameterNames(); while (initParameterNames.hasMoreElements()){ System.out.println("nextElement:"+initParameterNames.nextElement()); }
-
Share data as domain objects★
Domain objects: Objects that share data within a certain scope
The domain scope used by ServletContext is the entire web project
test:
1. In a Servlet, set shared data in the ServletContext object
2. Get the shared data in another Servlet
method:
servletcontext.setAttribute(string key,object obj); object msg servletcontext.getAttribute(string key); //移除指定的共享数据(指定key,删除对应的value) servletcontext.removeAttribute(Sstring key);
Case: Try to use SecondServlet to delete the shared data test created by myFirstServlet, and customize the value of test
The code demonstration is as follows:
//MyFirstServle新增共享数据test并显示 import javax.servlet.*; import java.io.IOException; public class MyFirstServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("触发了继承GenericServlet类的子类MyFirstServlet类的service方法......"); //如何在servletContext作用域范围内添加共享数据 ServletContext servletContext = servletRequest.getServletContext(); servletContext.setAttribute("msg","这是MyFirstServlet设置的共享数据"); //MyFirstServle新增共享数据test并显示 servletContext.setAttribute("test","这是MyFirstServlet设置的test共享数据"); System.out.println("test="+servletContext.getAttribute("test")); } }
//SecondServlet尝试删除并显示MyFirstServlet设置的共享数据test import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class SecondServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doPost方法"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doGet方法"); //如何获取MyFirstServlet在servletContext作用域范围内设置的共享数据 ServletContext servletContext = request.getServletContext(); Object msg = servletContext.getAttribute("msg"); System.out.println("msg="+msg); //删除MyFirstServlet设置的共享数据test servletContext.removeAttribute("test"); System.out.println("SecondServlet已经删除了共享数据test"); System.out.println("共享数据test="+servletContext.getAttribute("test")); } }
6. Interface for processing requests and responses
6.1 HttpservletRequest interface
Introduction:
This interface is a sub-interface of the ServletRequest interface, which encapsulates the relevant information of the HTTP request (all the information in the request message is encapsulated inside)
The main function:
-
Get request header information
request.getHeader(String key);
//获取请求头中客户端的产品信息 String header = request.getHeader("User-Agent"); System.out.println("客户端的产品信息如下"); System.out.println("header:"+header); //获取请求头中请求来源 String referer = request.getHeader("Referer"); System.out.println("请求来源如下"); System.out.println("referer:"+referer);
-
Get the path information of the url
request.getContextPath()//获取上下文路径 request.getServerName() //获取主机名 request.getServerPort() //获取端口号
//获取url String contextPath = request.getContextPath();//获取上下文路径 System.out.println("contextPath:"+contextPath); //获取主机名 String serverName = request.getServerName(); System.out.println("serverName:"+serverName); //获取端口号 int serverPort = request.getServerPort(); System.out.println("serverPort:"+serverPort);
-
Get request parameters ★
What are the request parameters?
The request parameter is the data submitted by the browser to the server.How does the browser send data to the server?
① Attached to the url (consistent with the get request, the form of splicing is the binding of the request data), as shown below:
http://localhost:8989/MyServlet/MyHttpServlet?userId=20&username=jack
② Submit via the form
<form action="MyHttpServlet" method="post"> 你喜欢的足球队<br /><br /> 巴西<input type="checkbox" name="soccerTeam" value="Brazil" /> 德国<input type="checkbox" name="soccerTeam" value="German" /> 荷兰<input type="checkbox" name="soccerTeam" value="Holland" /> <input type="submit" value="提交" /> </form>
Use the HttpServletRequest object to get request parameters
string request.getparameter(string key); string[] request.getparametervalues("hobby");
//获取请求参数 //根据表单的name值获取它的value值 String username = request.getParameter("username");//获取表单中name为username的value值,下同 System.out.println("username="+username); String password = request.getParameter("password"); System.out.println("password="+password); String gender = request.getParameter("gender"); System.out.println("gender="+gender); //如何根据一个name获取有多个并存的value值 String[] hobbies = request.getParameterValues("hobby"); System.out.println("hobbies:"); for (String hobby : hobbies) { System.out.println(hobby); }
-
Get request method
request.getMethod()
//获取请求方式 String method = request.getMethod(); System.out.println("请求方式:"); System.out.println("method:"+method);
-
Forward and share data
Forwarding is one of the main means of page jumping
What is forwarding? As shown below
The application scenarios are as follows:
a. Forward to the second servlet
//HttpServletRequest对象reg转发客户端请求至register_error的servlet中 req.getRequestDispatcher("register_error").forward(req,resp);
b. Forward to a web page
//HttpServletRequest对象reg转发客户端请求至网页register_error中 req.getRequestDispatcher("regist_error.html").forward(req,resp);
Steps for usage:
a. Obtain the transponder object
RequestDispatcher requestDispatcher=request.getRequestDispatcher(目标路径);
b. Perform forwarding operation (request and response need to be passed)
requestDispatcher.forward(request,response);
Code for page jump:
//跳转至root.html request.getRequestDispatcher("root.html").forward(request,response);
Can Secondservlet get the request parameters in the request?
Yes, because forwarding passes the request object
request can share data as a domain object (request domain)
The scope of data
应用域(ServletContext):
请求域(HttpServletRequest)
: The scope of data sharing is this request, when the response is over, the request is also over//添加共享数据 setAttribute(string key,object value); //获取共享数据 getAttribute(string key) //移除共享数据 removeAttribute(string kev)
6.2 HttpservletResponse interface
Introduction:
- This interface is a sub-interface of the ServletResponse interface, which encapsulates the relevant information of the server for the HTTP response. (Temporarily only server configuration information, no specific content related to the response body)
- The Servlet container creates its implementation class object and passes it into the service(HttpServletRequest req, HttpServletResponse res) method.
- The HttpServletResponse object refers to the HttpServletResponse implementation class object provided by the container.
The main function:
a. Output the response data to the client through the output stream
Printwriter writer=response.getwriter();
writer.write("<h1>success</h1>");
b. You can set the garbled characters of the response (the way to add the response header)
response.addHeader("Content-Type","text/html;charset=utf-8");
简写:response.setContentType("text/html;charset=utf-8");
c. Redirection
One of the main means of page jump
What are redirects? As shown below:
The application scenarios are as follows:
①Redirect to another Servlet
response.sendRedirect("second");
② Redirect to the page
response.sendRedirect("admin.html");
When the request parameters sent to the firstservlet request, can the secondservlet get it?
Unable to fetch; because the second request was sent (the request parameters in the first request have nothing to do with the second request)
Can redirects share data using the requested domain?
Can't
The difference between forwarding and redirection
Forward | redirect | |
---|---|---|
browser perception | Can't feel it | perceived |
URL in the URL bar | constant | will change |
number of requests | one request | two requests |
Request shared data in the domain | can visit | not accessible |
Initiator | request | response |
WEB-INF | can visit | not accessible |
target resource | resources on this server | Resources from other servers |
ps:
The resources under WEB-INF have a feature: the client cannot access them, but the server can access them, and you can put resources that you do not want the client to directly access under WEB-INF
7. Processing of request and response garbled characters
7.1 Request garbled characters
①
get请求
: tomcat8 has been processed
Notice:
If your Tomcat version is 7 or below, you need to modify the tomcat configuration file . Modify the Connector tag in the server.xml file and add the URIEncoding="utf-8" attribute, as shown in the following figure:
②
post请求
: Chinese garbled characters
solution:
Before getting the request parameters in the code, set the charset
code show as below:
request.setcharacterEncoding("utf-8");
Case: The form submits data to FirstServlet in post mode, demonstrating the post garbled problem
The code demonstration is as follows:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FirstServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求
//post方法的中文乱码问题
// request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println("username="+username);
String password = request.getParameter("password");
System.out.println("password="+password);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("触发了FirstServlet的doGet方法.......");
/* //设置请求域的共享数据
//注意,设置的共享数据需要放在使用请求转发的代码之前,不然另一个servlet无法获取之前设的请求域共享数据
request.setAttribute("requestMsg","这是requestMsg共享的数据");
request.setAttribute("msg","这是msg");
//实现转发跳转至secondservlet
// request.getRequestDispatcher("second").forward(request,response);
//实现重定向至secondservlet
response.sendRedirect("second");
*/
}
}
After adding the character set, modify it as follows:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FirstServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求
//post方法的中文乱码问题
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println("username="+username);
String password = request.getParameter("password");
System.out.println("password="+password);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("触发了FirstServlet的doGet方法.......");
/* //设置请求域的共享数据
//注意,设置的共享数据需要放在使用请求转发的代码之前,不然另一个servlet无法获取之前设的请求域共享数据
request.setAttribute("requestMsg","这是requestMsg共享的数据");
request.setAttribute("msg","这是msg");
//实现转发跳转至secondservlet
// request.getRequestDispatcher("second").forward(request,response);
//实现重定向至secondservlet
response.sendRedirect("second");
*/
}
}
7.2 Garbled response
Classification:
① Get the output stream and write data directly
It is written as follows:
response.addHeader("Content-Type","text/html;charset=utf-8);
//简写
response.setContentType("text/html;charset=utf-8");
Do not believe? Please see the demo below:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ResponseServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//添加响应头以规避中文乱码
// response.setContentType("text/html;charset=utf-8");
//输出响应数据流给客户端
PrintWriter writer = response.getWriter();
writer.print("<html>");
writer.print("<head>");
writer.print("</head>");
writer.print("<body>");
writer.print("<h1>success 成功</h1>");
writer.print("</body>");
writer.print("</html>");
}
}
The code as a whole remains unchanged, only one sentence of code is added as follows:
//添加响应头以规避中文乱码
response.setContentType("text/html;charset=utf-8");
//输出响应数据流给客户端
PrintWriter writer = response.getWriter();
②Forward
③Redirection
8. Case: login and registration function of connection database version
Case: To realize the login and registration function, it needs to be compared with the database
8.1 Registration function
step:
① Build the environment
-
Import the jar package (database driver package, database connection pool, DBUtils) and put it in the lib directory under WEB-INF
-
Create] DBCTools and BaseDao
-
The configuration file of the database connection pool (put it in the src directory)
-
Create users table in MySQL
-
Create an entity class (User)
② Write the registration function
- Create a registration page
- createUsersDAOlmpl
- Create a Registe'rServlet
Part of the code is provided here:
package DAO;
import bean.users;
import java.sql.SQLException;
public class UsersDAOlmpl extends BaseDAOImpl implements UsersDAO {
@Override
public users findUserByUsername(String username) {
String sql="select * from users where username=?";
try {
return getBean(users.class, sql, username);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean addUser(users user) {
String sql="insert into users values(null,?,?,?)";
try {
int len = update(sql, user.getUsername(), user.getPassword(), user.getEmail());
if (len>0){
return true;
}
return false;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package DAO;
import bean.users;
public interface UsersDAO {
//注册
//根据用户名来查找相应的用户信息
users findUserByUsername(String username); //登录
//添加用户
boolean addUser(users user);
}
8.2 Login function
step:
- Create a login page
- createUsersDAOlmpl
- Create LoginServlet
8.3 Realize the effect
①Test registration function
②Test login function
Nine. Use Beanutils to optimize code
Introduction:
Beanutils is a Java library that provides a set of utility classes for working with JavaBeans. JavaBeans are Java classes that follow certain conventions, such as having a default constructor and getter and setter methods for their properties. Beanutils provides methods for copying properties between JavaBeans, converting property values to strings, and performing other common JavaBeans-related tasks. It is part of the Apache Commons project and is widely used in Java applications.
Function:
Automatically map the data in the map collection to javaBean
Conditions of Use:
The key value in the Map collection must be consistent with the attribute name in the javaBean, otherwise the inconsistent key value will not be mapped
Steps for usage:
-
import jar package
① Copy the following three jar packages, and then paste them to the local dynamic web project to be applied under Web/WEB-INF/lib ②
Select the three jar packages just now in the lib directory, right-click to open –> Add as Library - -> Select the corresponding parameters in Create Library
-
Just use Beanutils to call the method directly
The case is as follows: use Beanutils to optimize the registration function in the case of the login and registration function of the connection database version above
The code demonstration is as follows:
import DAO.UsersDAOlmpl;
import bean.users;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理注册业务
/* String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
//数据库中user表的uid字段是自增长列
users user=new users(null,username,password,email);*/
//使用BeanUtils,减少代码冗余,这样即使注册表单中有300个name属性值,我也不用一个个手动输入,然后再一一添加进user对象里,那样代码量太大
Map<String, String[]> parameterMap = req.getParameterMap();//map集合中的key值是表单中的name属性值
users user=new users();
try {
BeanUtils.populate(user,parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
UsersDAOlmpl dao=new UsersDAOlmpl();
users userByUsername = dao.findUserByUsername(user.getUsername());
if (userByUsername==null){
dao.addUser(user);
req.getRequestDispatcher("regist_success.html").forward(req,resp);
}else {
req.getRequestDispatcher("regist_error.html").forward(req,resp);
}
}
}
10. The path problem of the web project★
10.1 url (commonly used)
Interpretation:
Uniform resource locator (find a resource from the entire network environment), such as http://localhost:9999/day06_servlet_war_exploded/login.html
相对路径
: relative to ur1 as a reference
绝对路径
: url is the absolute path (starting from the ip address)
The locations involved in the path are:
-
Hyperlinks, forms, links, img, scripts in web pages...
-
Forward
-
redirect
-
web.xml
Notice:
In the web project, add / before the path, using an absolute path
建议使用绝对路径,因为绝对路径一旦写死,不管该资源上有多少个上级目录,依然可以找到,若用相对路径,则要时刻注意该资源的上级目录的变化
What does / mean?
-
server resolution
从当前项目下开始找 例如http://localhost:9999/day06_servlet_war_exploded/
①web.xml
For example:
<!-- 设置访问loginservlet的路径 /login --> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>t1.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping>
The above example sets the access path of LoginServlet to access login directly from the project
<!-- 设置访问loginservlet的路径 /abc/login --> <servlet> <servlet-name>loginServlet</servlet-name> <servlet-class>t1.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/abc/login</url-pattern> </servlet-mapping>
The above example sets the access path of Loginservlet to find abc first under the project, and then find login under abc to find LoginServlet
② Forward
For example://建议使用绝对路径 request.getRequestDispatcher("/second").forward(request,response); //http://localhost:9999/day06_servlet_war_exploded/second
-
browser analysis
从当前服务器下去找 例如:在 http://localhost:9999/ 下去找
①All paths in the webpage (hyperlink, form, link, img, script...)
②Redirection
The code example is as follows:
response.sendRedirect("second");//不加/,默认前面是./second //重定向是在浏览器里解析,它是从当前服务器下去找,即http://localhost:9999/second去找,绝对找不到,遂报404 /* 解决方案:在second前面加上/day06_servlet_war_exploded/,这样就是在当前项目下去找second,一定能找到 即从http://localhost:9999/day06_servlet_war_exploded/second去找 但是这样写有一个弊端,若修改了上下文路径,代码里也得改,比较麻烦,扩展性不是很好 推荐这样写,即动态的获取上下文路径+/second response.sendRedirect(request.getContextPath()+"/second"); */
Summarize:
路径前加/,就是使用绝对路径 /的含义,由服务器解析就是当前项目下,由浏览器解析就是当前服务器下,网页内和重定向路径的/由浏览器解析。转发和web.ml中的/由服务器解析
10.2 uri (rarely used)
Interpretation:
Uniform Resource Identifier (find a resource from the current project)
For example
/day06_servlet_war_exploded/login.html
Find login.html under the war package named day06_servlet_war_exploded (web project deployed on the server)