手动设置标题以进行测试

时间:2011-08-28 10:09:57

标签: java servlets

我想创建一个servlet类,它接收来自jsp的两个输入参数,例如login.jsp和thae servlet“CommandQueueTestServlet”将那些incomming参数设置为头参数,然后将请求和响应参数发送到另一个servlet“CheckForCommandServlet ”。

我需要这样做只是为了测试我的功能,因为我的“CheckForCommandServlet”实际上会被其他一些有头参数的应用程序调用。

但是对于我自己的测试,我想创建一个servlet“CommandQueueTestServlet”来设置标题。

请检查以下代码我想解释的内容

javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

public class CommandQueueTestServlet extends HttpServlet{

 public void doGet(HttpServletRequest request,
         HttpServletResponse response)
throws ServletException, IOException {


String hwId=request.getParameter("hardware_id");
String panelistId=request.getParameter("panelist_id")); 

// Setting input parameter as header parameter.Since request object dont have setHeader so setting in response
//object

response.setHeader("x-HwId",hwid);
response.setHeader("x-panelistId,panelistId);

// creating instance of CheckForCommandServlet and passing in doGet() method:

CheckForCommandServlet headerParam= new CheckForCommandServlet();

 headerParam.doGet(request,response);


 }
 }

 // Code for CheckForCommandServlet 

 public class CheckForCommandServlet extends HttpServlet {

 @Override
 public void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {



    Enumeration enumeration = httpServletRequest.getHeaderNames();
    String headerName;
    String headerValue;
    while (enumeration.hasMoreElements())
    {
        headerName = (String)enumeration.nextElement();
        if (headerName == null)
        {
            headerName = "";
        }

        headerName = headerName.toLowerCase();
        headerValue = httpServletRequest.getHeader(headerName);
        logger.log(Level.INFO, "Header headerName " + headerName);
        logger.log(Level.INFO, "Header ParamaterValue " + headerValue);

    }

  }

我的CheckForCommandServlet如何获得在CommandQueueTestServlet中设置的headerParemeter,因为它是在header参数中设置的。

2 个答案:

答案 0 :(得分:2)

以下几行:

// Setting input parameter as header parameter.Since request object dont have setHeader so setting in response
//object

response.setHeader("x-HwId",hwid);
response.setHeader("x-panelistId,panelistId);

为将由servlet容器生成的HTTP响应添加两个标头,而不是向转发到CheckForCommandServlet servlet的HTTP请求添加。

由于您的目的是在原始请求中添加HTTP标头,以便后续的HttpServletRequest.getHeader()调用读取相应的值,您可以采用使用覆盖{{HttpServletRequestWrapperthis related StackOverflow answer的方法。 1}}方法,返回客户端发送的值。有关详细信息,请参阅Fiddler


为了验证getHeader的行为,更好的方法是使用像request headers automatically这样的HTTP调试代理。 Fiddler允许您将Apache HttpComponents添加到客户端发出的请求中。您需要做的就是确保客户端配置为使用Fiddler作为HTTP代理。

即使您打算编写轻量级单元测试,最好在客户端中使用类似{{3}}的HTTP库,而不是使用编写请求包装器和servlet的方法。需要构建特定于测试的WAR的额外开销。

答案 1 :(得分:1)

要扩展Vineet Reynolds的优秀答案,以下是使用java.net.HttpURLConnection设置HTTP标头的一种方法:

URL url = new URL("http://localhost:8080/CheckForCommandServlet");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("X-HwId", "Foo");
connection.setRequestProperty("X-panelistId", "Bar");
connection.setRequestMethod("GET");
connection.connect();
connection.getInputStream().close(); //Must open stream to make request.
connection.disconnect();

你可以在功能测试中结束这样的事情来断言其他事情的反应。


修改

使用HttpServletRequestWrapper

  1. 将标题设置为请求属性。
  2. 覆盖包装中的getHeader(String name)getHeaderNames()
  3. 使用包装器代替请求转发到目标servlet。
  4. 代码(请注意我为了简洁而删除了导入):

    public class CommandQueueTestServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            MyWrapper wrapper = new MyWrapper(request);
            request.setAttribute("X-HwId", "HardWare ID");
            request.setAttribute("X-PanelListId", "Panel List ID");
            request.getRequestDispatcher("/CheckForCommandServlet").forward(
                    wrapper, response);
        }
    
        private static class MyWrapper extends HttpServletRequestWrapper {
    
            public MyWrapper(HttpServletRequest request) {
                super(request);
            }
    
            @Override
            public String getHeader(String name) {
                String header = super.getHeader(name);
                return header == null ? (String) super.getAttribute(name) : header;
            }
    
            @Override
            @SuppressWarnings("unchecked")
            public Enumeration<String> getHeaderNames() {
                List<String> headerNames = Collections.list(super.getHeaderNames());
                headerNames.addAll(Collections.list(super.getAttributeNames()));
                return Collections.enumeration(headerNames);
            }
        }
    }
    

    您现在应该像往常一样使用request.getHeader(String name)

    public class CheckForCommandServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            response.getWriter()
                    .format("Hardware ID = %s\n Panel List ID = %s",
                            request.getHeader("X-HwId"),
                            request.getHeader("X-PanelListId"));
        }
    }
    

    即使这样可行,但这是一个相当脆弱的测试,正如Vineet已经提到的那样,它将要求你部署一个单独的WAR。恕我直言,在某种测试中使用servlet代码之外的HTTP库仍然是最好的方法。