ServletRequest
其实就是对于请求报文的封装。
HttpServletRequest----子接口。
请求报文:
请求行:请求方法 请求资源 版本号
请求头
请求体
request对象中分别提供了哪些API,用来获取请求报文的各个部分。
除此之外,request还提供了一些其他比较有趣的API。
如果前端页面提交的参数非常多,怎么写
@WebServlet("/submit2")
public class SubmitServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
String[] values = request.getParameterValues(name);
if(values.length == 1){
System.out.println(name + " = " + values[0]);
}else if(values.length > 1){
System.out.println(name + " = " + Arrays.toString(values));
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
如果想把这些数据封装到一个对象中,应该怎么办?
Java Bean。就是表示一个对象。成员变量应当是private。然后提供相应的get和set方法。
变量的名称首字母一定要小写,对应的get和set方法首字母大写。
username=xx&password=xx&gender=xx&
package com.cskaoyan.request.bean;
import java.util.Arrays;
public class User {
private String username;
private String password;
private String gender;
private String[] hobby;
private String description;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", hobby=" + Arrays.toString(hobby) +
", description='" + description + '\'' +
'}';
}
}
@WebServlet("/submit3")
public class SubmitServlet3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map parameterMap = request.getParameterMap();
//可不可以利用反射将这些参数封装到user对象中
//思路:首先提供一个user对象,拿到它所有的set方法
//parameterMap可不可以迭代出键值对name-value
// set + name的首字母大写, setXxxx
//set方法迭代,setXxx是否与某个set方法的名称一致,如果一致
//则调用method.invoke完成当前参数的赋值
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
@WebServlet("/submit4")
public class SubmitServlet4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
Map parameterMap = request.getParameterMap();
//EE阶段如何导包
//lib目录一定要放在WEB-INF目录下
User user = new User();
try {
//它是怎么实现的?反射
BeanUtils.populate(user, parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(user);
//JDBC代码
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println(username);
}
}
http://localhost:8080/app/submit4
首先看一下你当前页面路径:
http://localhost:8080/app/form.html
你需要提交的路径
http://localhost:8080/app/submit4
所以相对路径写法就是如何从当前路径变成提交路径
submit4
/app/submit4
第三种是推荐的方式。
区公司开发,会遇到三个环境:开发环境(本地)、测试环境(局域网内某个ip地址)、生产环境
所以第一种路径写法不是非常推荐。会涉及到路径的频繁变更。但是也并不是绝对不可以用,可以将这些以配置文件的形式配置下来。
第二种路径写法:提交的路径会很依赖于当前页面路径,比如当前页面路径发生变更,那么提交的路径就会跟着变更
如果一个请求需要用到多个servlet共同来处理,怎么做?
为什么需要用到多个servlet来参与?代码全部写在一个servlet中不就可以了吗?
分工协作的思想。每一个模块只负责一个功能点,每个模块功能尽可能单一,那么它的
复用性就越好。
需求1:功能1、功能2、功能3
需求2:功能2、功能3、功能4
请求首先访问到servlet1,接下来请求转发或者包含servlet2,那么这两个组件之间有一个称呼,servlet1叫做源组件、servlet2叫做目标组件
路径写法:
1.全路径(不可行,因为路径只会被当做当前应用下的一个资源)
3./应用名/资源名
如果不加应用名呢?
以/开头的路径写法:有的地址需要加/应用名,有的不需要加,直接/资源名即可,那么有什么规律吗?
看执行主体是服务器还是浏览器(这个路径是给谁使用的),如果是服务器处理,那么就不需要加,如果是浏览器使用的,那么就需要加。
首先,两者都是用来介导多个servlet参与到一个请求中的,但是两者之间也存在很多差异。
转发:
源组件处理部分请求之后,接下来将请求交给目标组件全权处理,自己不再过多干预响应。
包含:
源组件将目标组件包含到自身中,然后一并做出响应。
看主动权的问题。代码上面的体现是什么样的呢?
对于转发来说,源组件转发过后,在最终的响应中只能留下响应头,无法留下响应体(留头不留体)
但是包含来说,源组件包含过后,在最终的响应中不仅可以留下响应头,还可以留下响应体(留头也留体)
使用场景:
转发一般用在servlet和页面之间
包含一般用在页面和页面之间
@WebServlet("/dispatcher1")
public class DispatcherServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//输入目标组件的地址:1.全路径 2.相对路径
response.setHeader("content-type","text/html;charset=utf-8");
response.getWriter().println("dispatcher1");
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/dispatcher2");
//转发是forward 包含是include
requestDispatcher.include(request, response);
}
}
@WebServlet("/dispatcher2")
public class DispatcherServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("dispatcher2");
}
}
看包含