Request
1、HttpServletRequest
一、HttpServletRequest概述
咱們在建立Servlet時會覆蓋service()方法,或doGet()/doPost(),這些方法都有兩個參數,一個爲表明請求的request和表明響應response。
service方法中的request的類型是ServletRequest,而doGet/doPost方法的request的類型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更增強大。
request對象是JSP中重要的對象,每一個request對象封裝着一次用戶請求,而且全部的請求參數都被封裝在request對象中,所以request對象是獲取請求參數的重要途徑。
二、Request的運行流程
同Response。
三、request得到請求內容
請求行
得到客戶端的請求方式: String getMethod();
得到請求的資源: String getContextPath();---web應用的名稱
String getRequestURI()
StringBuffer getRequestURL()
String getContextPath() ---web應用的名稱
String getQueryString() ---- get提交url地址後的參數字符串
//一、得到請求方式
String method = request.getMethod();
System.out.println("method:"+method);
//二、得到請求的資源相關的內容
String requestURI = request.getRequestURI();
StringBuffer requestURL = request.getRequestURL();
System.out.println("uri:"+requestURI);
System.out.println("url:"+requestURL);
//得到web應用的名稱
String contextPath = request.getContextPath();
System.out.println("web應用:"+contextPath);
//地址後的參數的字符串
String queryString = request.getQueryString();
System.out.println(queryString);
//三、得到客戶機的信息---得到訪問者IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println("IP:"+remoteAddr);
注意:request得到客戶機(客戶端)的一些信息
request.getRemoteAddr() --- 得到訪問的客戶端IP地址
請求頭
得到指定請求頭: String getHeader(String name);
獲取全部請求頭的名稱:java.util.Enumeration<String> getHeaderNames();
long getDateHeader(String name)
String getHeader(String name)
Enumeration getHeaderNames()
Enumeration getHeaders(String name)
int getIntHeader(String name)
//一、得到指定的頭
String header = request.getHeader("User-Agent");
System.out.println(header);
//二、得到全部的頭的名稱
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName+":"+headerValue);
}
referer 頭的做用:執行該此訪問的來源作防盜鏈
請求體
請求體中的內容是經過post提交的請求參數,格式是:
username=zhangsan&password=123&hobby=football&hobby=basketball
key ---------------------- value
username [zhangsan]
password [123]
hobby [football,basketball]
獲取paramName請求參數的值:
String getParameter(String paramName);
paramName請求參數的值,當該請求參數有多個值時,該方法將返回多個值所組成的數組:
String[] getParameterValues(String name);
獲取全部請求參數名和參數值所組成的Map對象
Map<String,String[]> getParameterMap();
獲取全部請求參數名所組成的Enumeration對象
Enumeration getParameterNames();
//一、得到單個表單值
String username = request.getParameter("username");
System.out.println(username);
String password = request.getParameter("password");
System.out.println(password);
//二、得到多個表單的值
String[] hobbys = request.getParameterValues("hobby");
for(String hobby:hobbys){
System.out.println(hobby);
}
//三、得到全部的請求參數的名稱
Enumeration<String> parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()){
System.out.println(parameterNames.nextElement());
}
System.out.println("------------------");
//四、得到全部的參數 參數封裝到一個Map<String,String[]>
Map<String, String[]> parameterMap = request.getParameterMap();
for(Map.Entry<String, String[]> entry:parameterMap.entrySet()){
System.out.println(entry.getKey());
for(String str:entry.getValue()){
System.out.println(str);
}
System.out.println("---------------------------");
}
注:Map複雜了一點,可是比較有用。
注意:不管是get請求方式仍是post請求方式,上述的方法同樣能夠得到。
四、Request的其餘功能
a、request是一個域對象
request對象也是一個存儲數據的區域對象,因此也具備以下方法:
setAttribute(String name, Object o)
getAttribute(String name)
removeAttribute(String name)
注意:request域的做用範圍:一次請求中
在request中存儲數據,而後經過請求轉發可以獲取到(重定向沒有數據)。(a與b結合來看)
b、request完成請求轉發
得到請求轉發器----path是轉發的地址
RequestDispatcher getRequestDispatcher(String path)
經過轉發器對象轉發
requestDispathcer.forward(ServletRequest request, ServletResponse response)
//servlet1將請求轉發給servlet2
RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet2");
dispatcher.forward(request, response);
注意:轉發與重定向的區別?
1)重定向兩次請求,轉發一次請求
2)重定向地址欄的地址變化,轉發地址不變
3)從新定向能夠訪問外部網站 轉發只能訪問內部資源
4)轉發的性能要優於重定向
重定向是服務器外部行爲,請求轉發是服務器內部行爲。
注意:ServletContext域與Request域的生命週期比較?
ServletContext:
建立:服務器啓動
銷燬:服務器關閉
域的做用範圍:整個web應用
request:
建立:訪問時建立request
銷燬:響應結束request銷燬
域的做用範圍:一次請求中
注意:客戶端地址與服務器端地址的寫法?
客戶端地址:是客戶端去訪問服務器的地址,服務器外部的地址。其特色:寫上Web應用的名稱。
客戶端地址有:直接輸入地址;重定向;
服務器端地址:服務器內部資源跳轉的地址。其特色:不須要寫Web應用的名稱。
2、完成用戶註冊
一、獲取表單的數據
二、將數據存儲到數據庫中
注意:中文亂碼問題;BeanUtils:將Map中的數據映射到實體中(JavaBean),根據map的key與實體的屬性進行對比。
註冊的基本實現:
一、完成登陸頁面(html or jsp)
二、JDBC工具類實現
jar包:c3po.....dbutils.......mysql-connector....
c3p0-config.xml
DataSourceUtils.java
三、JavaBean實現User(實體數據封裝到JavaBean中,數據工整,面向對象思想)
四、註冊servlet實現
//1.獲取數據
//String username = request.getParameter("username");
//String password = request.getParameter("password");
//2.將散裝的數據封裝到JavaBean中
//User user = new User();
//user.setName(username);
//user.setPassword(password);
//1.2使用BeanUtils進行自動映射封裝
//BeanUtils工做原理:將map中的數據,根據key與實體的屬性的對象關係封裝
//只要key的名字與實體的屬性的名字同樣,就自動封裝到實體中
Map<String, String[]> properties = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user, properties);
} catch (IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//如今這個位置user對象已經封裝好了
//手動封裝uid----uuid----隨機的不重複的字符串32位
//java代碼生成後是36位
user.setUid(UUID.randomUUID().toString());
response.getWriter().write(user.toString());
//3.將參賽傳遞給一個業務操做方法
try {
regist(user);
response.getWriter().write("regist success");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
注:紅色部分須要添加jar包:beanutils 及 loggingjar包
解決獲取數據的中文亂碼問題?
//設置request的編碼-----只適合post方式
request.setCharacterEncoding("UTF-8");
亂碼過程:王五----使用UTF-8編碼------使用iso8859-1解碼------亂碼xxx,
實現亂碼的解決:xxx------使用iso8859-1編碼------使用utf-8解碼----王五
編碼:str.getByte("iso8859-1");
new String(string,"utf-8");
//get方式亂碼解決
String username = request.getParameter("username");//亂碼
//先用iso8859-1編碼,再使用utf-8解碼
username = new String(username.getBytes("iso8859-1"),"UTF-8");
適用於get post
get不適用於表單提交。
用戶登陸失敗的信息回顯
//4.認爲註冊成功跳轉到登陸頁面
//使用重定向,而非轉發(地址變化)
response.sendRedirect(request.getContextPath()+"/login.jsp");
爲何使用request.getContextPath();
3、用戶登陸失敗的信息回顯
步驟:
一、用戶登陸
二、輸入用戶名密碼
三、用戶名及密碼正確,跳轉到首頁(重定向)
四、用戶名或密碼不正確
五、轉向登陸頁面,提示用戶名或者密碼錯誤
技術點:
一、登陸頁面設計(html or jsp)
表單form的action跳轉到對應的servelt進行處理。
<form class="form-horizontal" action="/WEB15_Request/login" method="post">
二、LoginServlet.java (登陸處理頁面)
//0、設置Request編碼
request.setCharacterEncoding("UTF-8");
//1.獲取用戶名和密碼
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.調用一個業務方法進行該用戶查詢
User login = null;
try {
login = login(username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.經過user是否爲null判斷用戶名和密碼是否正確
if(login!=null) {
//用戶名和密碼正確
//登陸成功跳轉到網站的首頁(重定義)
response.sendRedirect(request.getContextPath());
}else {
//用戶名或密碼錯誤
//跳回當前頁面login.jsp
//使用轉發到login.jsp向
request.setAttribute("loginInfo","用戶名或密碼錯誤");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public User login(String username, String password) throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select * from user where username = ? and password = ?";
User user = runner.query(sql, new BeanHandler<User>(User.class),username,password );
return user;
}
三、登陸頁面錯誤回顯代碼 jsp
<div> <%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo")%></div>
使用三目運算符,若是直接request話,會顯示null在登陸頁面上面。
四、其餘,暫無。
4、總結
一、request得到行的內容(請求參數)
request.getMethod();
request.getRequestURI();
request.getRequestURL();
request.getContextPath();
request.getRemoteAddr();
二、request得到頭的內容
request.getHeader(name);
三、request得到體(請求參數)
String request.getParameter(name);
Map<String, String[]> request.getParameterMap();
String[] request.getParametherValues(name);
注意:客戶端發送的參數到服務器端得到的值都是字符串。
中文亂碼問題:
post:
request.setCharacterEncoding("UTF-8");
get(原始方法):
username = new String(username.getBytes("iso8859-1"),"UTF-8");
四、request其餘內容 (轉發和域)
在域存儲數據:
request.setAttribute(name,value);
request.getAtteribute(name);
轉發:
request.getRequestDispatcher(轉發的地址(服務器內部地址)).forward(request,response);