高效掌握Request的API
从现实的开发角度考虑,当与前端,移动端等协同开发项目的时候,每个servlet的接口调试是最为频繁的一步操作。
调试过程中,查看request的信息必不可少。
从学习角度考虑,需要善于查看Request中的各部分信息,帮助理解
所以本文主题是 在IDEA中快速查看每个servlet中的request信息 如图:
针对开发中与学习时的两种情况,给出两种方案
学习时
修改servlet的模板,添加获取request信息的方法。
如何修改servlet的模板?
以IDEA为例,点击左上角的File -> Settings -> 在Editor分类中 -> 选中 File and Code Templates -> Other 修改servlet模板,修改模板的内容为自定义内容。
把模板中的内容替换为以下代码:
再次创建servlet的时候就可以很方便的查看Request中的信息了
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
@javax.servlet.annotation.WebServlet(urlPatterns = "/${Entity_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
this.setUTF8(request, response);
this.getReuestAllMsg(request, response);
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
this.doPost(request,response);
}
/**
* 统一给 请求和响应 设置UTF-8 编码
* @param request
* @param response
* @throws UnsupportedEncodingException
*/
public void setUTF8(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
}
/**
* 获取request 的全部信息
* @param request
* @param response
*/
public void getReuestAllMsg(HttpServletRequest request, HttpServletResponse response){
System.out.println("当前类被访问了 :" + ${Class_Name}.class);
this.getRequestLineMsg(request,response);
this.getRequestHeaderMsg(request, response);
this.getRequestParameterMsg(request, response);
}
/**
* 获取 request 请求行的全部信息
* @param request
* @param response
*/
public void getRequestLineMsg(HttpServletRequest request, HttpServletResponse response){
System.out.println("============= 获取请求行(请求方式 url 协议版本)的信息 ==============");
System.out.println("请求方式:"+request.getMethod());
System.out.println("虚拟目录:"+request.getContextPath());
System.out.println("资源路径:"+request.getServletPath());
System.out.println("URI:"+request.getRequestURI());
System.out.println("URL:"+request.getRequestURL());
System.out.println("协议版本:"+request.getProtocol());
System.out.println("客户端的IP地址:"+request.getRemoteAddr());
}
/**
* 获取 request 请求头中全部的键值对
* @param request
* @param response
*/
public void getRequestHeaderMsg(HttpServletRequest request, HttpServletResponse response){
System.out.println("============== 获取请求头的全部键值对 ===================");
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String key = headerNames.nextElement();
String value = request.getHeader(key);
System.out.println(key +" = "+ value);
}
}
/**
* 获取 request 中的全部参数信息
* @param request
* @param response
* @param useAND 当一个请求参数有多个值时 true 把数据显示成&格式 hobby=sport&hobby=study
* false 把数据显示成数组格式
*/
public void getRequestParameterMsg(HttpServletRequest request, HttpServletResponse response,Boolean useAND){
System.out.println("=============== 获取请求参数 ===============");
// (post请求下,从请求体获取请求参数)
// http://url?username=xuan1234&userpassword=123&hobby=sport&hobby=study
Map<String, String[]> parameterMap = request.getParameterMap();
//获取全部的请求参数 以及请求值
Set<String> parameterNames = parameterMap.keySet();
if (useAND){
this.useANDType(parameterNames,parameterMap);
}else {
this.useArrType(parameterNames,parameterMap);
}
}
//使用数组格式
public void useArrType(Set<String> parameterNames,Map<String, String[]> parameterMap){
for (String parameterName : parameterNames) {
String[] values = parameterMap.get(parameterName);
for (int i = 0; i < values.length; i++) {
if (values.length>1){
if (i==0){
System.out.print(parameterName +" = {"+values[i]+",");
}else if (i==values.length-1){
System.out.println(values[i]+"}");
}else {
System.out.print(values[i]+",");
}
}else {
System.out.println(parameterName +" = "+values[i]);
}
}
}
}
//使用&格式
public void useANDType(Set<String> parameterNames,Map<String, String[]> parameterMap){
for (String parameterName : parameterNames) {
String[] values = parameterMap.get(parameterName);
for (int i = 0; i < values.length; i++) {
if (values.length>1){
if (i==values.length-1){
System.out.println(parameterName + "=" +values[i]);
}else {
System.out.print(parameterName +"="+values[i] +" & ");
}
}else {
System.out.println(parameterName +" = "+values[i]);
}
}
}
}
/**
* 获取 request 中的全部参数信息
* @param request
* @param response
*/
public void getRequestParameterMsg(HttpServletRequest request, HttpServletResponse response){
this.getRequestParameterMsg(request,response,false);
}
}
开发中
写基类BaseServlet,在里面添加获取request信息的方法。
思路:利用继承,在项目中创建一个BaseServlet继承自HttpServlet , 然后之后的业务servlet 都继承自BaseServlet , 在BaseServlet中重写service()方法,添加获取Request信息的方法,这样往后再项目中调试每条URL servlet的时候控制台都会输出每个servlet的请求信息。
编写一个BaseServlet ,在内部通过方法分发(利用反射)来完成对应模块的功能调用。以及快速查看每个方法的request信息。
开发中,业务servlet如下
用户操作相关的 ("/ User") 对应着一个userServlet
用户登录 | 用户注册 | 用户退出登录 |
---|---|---|
User/LogIn | User/register | User/LogOut |
商品操作相关的 ("/Goods") 对应着一个goodsServlet
商品购买 | 商品加入到购物车 | 收藏商品 | 商品分享 |
---|---|---|---|
Goods/Buy | Goods/addToShopCar | Goods/Favorite | Goods/Share |
BaseServlet 中重写 Service方法
public class LXBaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取 request 请求的信息
this.getReuestAllMsg(req, resp);
this.setUTF8(req, resp);
//获取请求路径,以及方法名
String requestURI = req.getRequestURI();
String methodName = requestURI.substring(requestURI.lastIndexOf('/') + 1);
try {
//通过反射来执行方法
Method declaredMethod = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
declaredMethod.setAccessible(true);
declaredMethod.invoke(this, req, resp);
} catch (NoSuchMethodException e) {
System.out.println("你在浏览器输错了URL了,servlet中没有定义"+methodName+"方法");
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
对应的业务servlet类
@WebServlet("/user/*")
public class UserServlet extends LXBaseServlet{
void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("用户登录了。。。。。。。");
}
void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("用户退出登录了。。。。。。。。。");
}
void register(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("新用户注册了。。。。。。。。。");
}
}
在浏览器访问中对应功能的URI 同时会把request的信息也log出来了
http://localhost/LXUserProject/user/register
http://localhost/LXUserProject/user/login
http://localhost/LXUserProject/user/logout
好了,希望各位可以快速掌握Java Request中的API,谢谢