java 手动设置标题进行测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7220273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:10:01  来源:igfitidea点击:

Manually setting header for testing

javaservlets

提问by vibhas

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".

我想创建一个 servlet 类,它从 jsp 接收两个输入参数,比如说 login.jsp 和 servlet“CommandQueueTestServlet”将这些传入参数设置为标头参数,然后将请求和响应参数发送到另一个 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.

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

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

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

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.

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

回答by Vineet Reynolds

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 CheckForCommandServletservlet.

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

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 HttpServletRequestWrapperthat overrides the getHeadermethod, to return the values sent by the client. More details can be found in this related StackOverflow answer.

由于您的目的是在原始请求中添加一个 HTTP 标头,以便后续HttpServletRequest.getHeader()调用可以读取适当的值,因此您可以采用使用 aHttpServletRequestWrapper覆盖该getHeader方法的方法,以返回客户端发送的值。更多细节可以在这个相关的 StackOverflow 答案中找到



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 automaticallyto 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.

为了验证 的行为,更好的方法CheckForCommandServlet是使用 HTTP 调试代理,如Fiddler。Fiddler 允许您将请求标头自动添加到客户端发出的请求中。您需要做的就是确保将客户端配置为使用 Fiddler 作为 HTTP 代理。

Even if your intention is to write a light-weight unit test, it would be preferable to use a HTTP library like Apache HttpComponentsin 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.

即使您打算编写轻量级单元测试,最好在客户端中使用 HTTP 库(如Apache HttpComponents),而不是涉及编写请求包装器和 servlet 的方法,并且需要额外的开销要构建的特定于测试的 WAR。

回答by Sahil Muthoo

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

为了扩展 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();

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

您可以在功能测试中包含这样的内容,以断言响应等内容。



EDIT

编辑

Using the HttpServletRequestWrapper:

使用 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.
  1. 将标头设置为请求属性。
  2. 覆盖getHeader(String name)getHeaderNames()在您的包装器中。
  3. 使用包装器代替请求转发到目标 servlet。

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:

您现在应该可以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"));
    }
}

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.

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