开发者

Manually setting header for testing

I want to create a servlet class which receives two input parameters from a jsp let say login.jsp and thae servlet "CommandQueueTestServlet" set those incomming parameter as a header parameter and then send the request and response parameter to another servlet "CheckForCommandServlet".

I need to do this just to test my functionality because my "CheckForCommandServlet" will actually be invoked by some other application which has header parameter.

But for my own testing I want to create a servlet "CommandQueueTestServlet" for setting header.

Please check the below code what I am trying to explain

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);

    }

  }

How did my CheckForCommandServlet get the headerParemeter set in CommandQueueTestServlet as it is set in header parameter.


The following lines:

// 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);

adds two headers to the HTTP response that will be generated by the servlet container, and not to the HTTP request that is forwarded to the CheckForCommandServlet servlet.

Since your intention is to add a HTTP header to the original request so that a subsequent HttpServletRequest.getHeader() invocation would read the appropriate value, you may adopt the approach of using a HttpServletRequestWrapper that overrides the getHeader method, to return the values sent by the client. More details can be found in this related StackOverflow answer.


A better approach for the purpose of verifying the behavior of the CheckForCommandServlet, would be to use a HTTP debugging proxy like Fiddler. Fiddler allows you to add request headers automatically to a request issued by a client. All you need to do is to ensure that the client is configured to use Fiddler as the HTTP proxy.

Even if your intention is to write a light-weight unit test, it would be preferable to use a HTTP library like Apache HttpComponents in a client, instead of an approach that involves writing a request wrapper and a servlet with the additional overhead of requiring a test-specific WAR to built.


To expand upon Vineet Reynolds' excellent answer, Here's one way you can set HTTP headers using java.net.HttpURLConnection:

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();

You can wrap up something like this in your functional tests to assert on the response amongst other things.


EDIT

Using the HttpServletRequestWrapper:

  1. Set the headers as request attributes.
  2. Override getHeader(String name) and getHeaderNames() in your wrapper.
  3. Forward to the target servlet using the wrapper in-place of the request.

Code (note that I've removed imports for brevity):

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);
        }
    }
}

You should now be able to use request.getHeader(String name) as usual:

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"));
    }
}

Even though this works, it's a rather brittle test and as Vineet has already mentioned, will require you to deploy a separate WAR. IMHO, using an HTTP library outside of servlet code in a test of some sort is still the best way to go.


If you want to add headers to your HttpServletRequest, try this:

MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
mutableRequest.putHeader("header", "headerValue");

where request is your HttpServletRequest object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜