GVKun编程网logo

注入HttpServletRequest(注入骨水泥好后悔死了)

6

本文将分享注入HttpServletRequest的详细内容,并且还将对注入骨水泥好后悔死了进行详尽解释,此外,我们还将为大家带来关于HK2没有为球衣注入HttpServletRequest、Http

本文将分享注入HttpServletRequest的详细内容,并且还将对注入骨水泥好后悔死了进行详尽解释,此外,我们还将为大家带来关于HK2没有为球衣注入HttpServletRequest、HttpServletRequest & HttpServletResponse 中 Body 的获取、HttpServletRequest HttpServletResponse 常见操作、HttpServletRequest HttpServletResponse 接口详解的相关知识,希望对你有所帮助。

本文目录一览:

注入HttpServletRequest(注入骨水泥好后悔死了)

注入HttpServletRequest(注入骨水泥好后悔死了)

我正在使用ejb 3并尝试@Inject HttpServletRequest,但是在部署时发生异常。

码:

@Inject private HttpServletRequest httpRequest;

例外:

org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [HttpServletRequest] with qualifiers [@Default] at injection point [[field] @Inject private com.kmware.ttk.highway.beans.session.UserSessionBean.httpRequest]

我该怎么办?

答案1

小编典典

HttpServletRequest的生命周期由EJB /
Web容器而不是CDI容器管理。尝试注入它会导致问题,因为通常会有很多接口实现,并且您的CDI容器没有足够的信息来决定要注入哪种实现。即使您成功注入了它的实例,它也
不会 与EJB容器所管理的实例相同。

要获取正确管理的请求实例,请执行以下操作:

@Contextprivate HttpServletRequest httpRequest;

HK2没有为球衣注入HttpServletRequest

HK2没有为球衣注入HttpServletRequest

我正在尝试按照此处的示例创建工厂以注入HttpSession。不幸的是,无论我尝试什么,都无法正常工作。不知道可能是什么问题。

我试过只注入HttpServletRequest和提供程序。这是我使用提供程序的示例。尝试在provide方法中访问提供程序时,该错误是空指针异常。如果我尝试注入HttpServletRequest,那么将无法获取任何对象。我正在使用JerseyTest在GrizzlyTestContainer中运行它。为了绑定HttpServletRequest,我需要添加一些内容吗?我似乎找不到一个例子。

public class HttpSessionFactory implements Factory<HttpSession> {    private final HttpServletRequest request;    @Inject    public HttpSessionFactory(Provider<HttpServletRequest> requestProvider) {        this.request = requestProvider.get();    }    @Override    public HttpSession provide() {       return request.getSession();    }    @Override    public void dispose(HttpSession t) {    }}

答案1

小编典典

您应该@Override protected DeploymentContextconfigureDeployment()JerseyTest中返回ServletDeploymentContext。例如

import javax.inject.Inject;import javax.inject.Provider;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.core.Response;import org.glassfish.hk2.api.Factory;import org.glassfish.hk2.utilities.binding.AbstractBinder;import org.glassfish.jersey.server.ResourceConfig;import org.glassfish.jersey.servlet.ServletContainer;import org.glassfish.jersey.test.DeploymentContext;import org.glassfish.jersey.test.JerseyTest;import org.glassfish.jersey.test.ServletDeploymentContext;import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;import org.glassfish.jersey.test.spi.TestContainerException;import org.glassfish.jersey.test.spi.TestContainerFactory;import org.junit.Test;public class ServletTest extends JerseyTest {    @Path("/session")    public static class SessionResource {        @Inject        HttpSession session;        @GET        public Response getSessionId() {            return Response.ok(session.getId()).build();        }    }    public static class HttpSessionFactory implements Factory<HttpSession> {        private final HttpServletRequest request;        @Inject        public HttpSessionFactory(Provider<HttpServletRequest> requestProvider) {            this.request = requestProvider.get();        }        @Override        public HttpSession provide() {            return request.getSession();        }        @Override        public void dispose(HttpSession t) {        }    }    @Override    protected TestContainerFactory getTestContainerFactory() {        return new GrizzlyWebTestContainerFactory();    }    @Override    protected DeploymentContext configureDeployment() {        ResourceConfig config = new ResourceConfig(SessionResource.class);        config.register(new AbstractBinder() {            @Override            protected void configure() {                bindFactory(HttpSessionFactory.class).to(HttpSession.class);            }        });        return ServletDeploymentContext.forServlet(                                 new ServletContainer(config)).build();    }    @Test    public void test() {        System.out.println(target("session").request().get(String.class));    }}
  • 您可以在源代码测试中看到更多示例

HttpServletRequest & HttpServletResponse 中 Body 的获取

HttpServletRequest & HttpServletResponse 中 Body 的获取

获取 HttpServletRequest 中的请求体

    HttpServletRequest#getInputStream() 获取到请求的输入流,从该输入流中可以读取到请求体。不过这个流在被我们的代码 read 过后,之后的代码就会报错,因为流已经被我们读取过了 , 尝试使用 mark() , reset() 也是不行的,会抛出异常。可以通过将 HttpServletRequest 对象包装一层的方式来实现这个功能。

package org.hepeng.commons.http;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.io.IOUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 
 * @author he peng
 * @date 2018/9/11
 */
public class BodyCachingHttpServletRequestWrapper extends HttpServletRequestWrapper {


    private byte[] body;
    private ServletInputStreamWrapper inputStreamWrapper;

    public BodyCachingHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.body = IOUtils.toByteArray(request.getInputStream());
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.body);
        this.inputStreamWrapper = new ServletInputStreamWrapper(byteArrayInputStream);
        resetInputStream();
    }

    private void resetInputStream() {
        this.inputStreamWrapper.setInputStream(new ByteArrayInputStream(this.body != null ? this.body : new byte[0]));
    }

    public byte[] getBody() {
        return body;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return this.inputStreamWrapper;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.inputStreamWrapper));
    }


    @Data
    @AllArgsConstructor
    private static class ServletInputStreamWrapper extends ServletInputStream {

        private InputStream inputStream;

        @Override
        public boolean isFinished() {
            return true;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return this.inputStream.read();
        }
    }
}

 

获取 HttpServletResponse 中的响应体

    通过使用 ByteArrayOutputStream 将原 HttpSevletResponse 进行一层包装就可以实现。ByteArrayOutputStream 是将数据写入到它内部的缓冲区中,这样我们就可以获取到这个数据了。

package org.hepeng.commons.http;

import lombok.AllArgsConstructor;
import lombok.Data;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

/**
 * @author he peng
 * @date 2018/10/1
 */
public class BodyCachingHttpServletResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    private HttpServletResponse response;

    public BodyCachingHttpServletResponseWrapper(HttpServletResponse response) {
        super(response);
        this.response = response;
    }

    public byte[] getBody() {
        return byteArrayOutputStream.toByteArray();
    }

    @Override
    public ServletOutputStream getOutputStream() {
        return new ServletOutputStreamWrapper(this.byteArrayOutputStream , this.response);
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(new OutputStreamWriter(this.byteArrayOutputStream , this.response.getCharacterEncoding()));
    }


    @Data
    @AllArgsConstructor
    private static class ServletOutputStreamWrapper extends ServletOutputStream {

        private ByteArrayOutputStream outputStream;
        private HttpServletResponse response;

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setWriteListener(WriteListener listener) {

        }

        @Override
        public void write(int b) throws IOException {
            this.outputStream.write(b);
        }

        @Override
        public void flush() throws IOException {
            if (! this.response.isCommitted()) {
                byte[] body = this.outputStream.toByteArray();
                ServletOutputStream outputStream = this.response.getOutputStream();
                outputStream.write(body);
                outputStream.flush();
            }
        }
    }
}

flush() 函数是必须提供的 ,否则流中的数据无法响应到客户端 , ByteArrayOutputStream 没有实现 flush() 。像 SpringMVC 这类框架会去调用这个响应输出流中的 flush() 函数 ,而且有可能在出现多次调用的情况,多次调用会产生问题使得客户端得到错误的数据,比如这样的 :

{"errorCode":30001,"errorMsg":"用户未认证","token":null,"entity":null}{"errorCode":30001,"errorMsg":"用户未认证","token":null,"entity":null}  ,出现这种情况就说明 flush() 被调用了两次。所以需要在这里判断一下 HttpServletResponse#isCommitted()  。

获取请求体、相应体的包装类在 Filter 中的使用

package org.hepeng.commons.http.filter;

import com.tepin.commons.http.BodyCachingHttpServletRequestWrapper;
import com.tepin.commons.http.BodyCachingHttpServletResponseWrapper;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author he peng
 * @date 2018/10/2
 */
public class DemoFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        BodyCachingHttpServletRequestWrapper requestWrapper =
                new BodyCachingHttpServletRequestWrapper((HttpServletRequest) request);

        byte[] requestBody = requestWrapper.getBody();

        // TODO do something
        BodyCachingHttpServletResponseWrapper responseWrapper =
                new BodyCachingHttpServletResponseWrapper((HttpServletResponse) response);

        chain.doFilter(requestWrapper , responseWrapper);

        byte[] responseBody = responseWrapper.getBody();
        // TODO do something

    }

    @Override
    public void destroy() {

    }
}

 

HttpServletRequest HttpServletResponse 常见操作

HttpServletRequest HttpServletResponse 常见操作

一,HttpServletResponse 

   response.getWriter().write("<h1>response</h1>");以字符流的方式写数据

   response.getOutputStream().write("response"):以字节流的方式写数据

   response.setCharacterEncoding("utf-8"):设定响应数据为utf-8,字符流

   response.setHeader("Content-Type","text/html;charset=utf-8”):设置页面编码

   response.setContentType("text/html;charset=UTF-8");"):解决响应数据乱码

二,HttpServletRequest  获取客户机信息

   getRequestURL():获取资源请求完整路径

   getRequestURI():获取资源部分路径

   getQueryString ():方法返回请求行中的参数部分。

   getRemoteAddr():获取发出请求客户机的IP

   getRemotePort():获取发出请求客户机的端口

   getRemoteHost():获取发出请求客户机名称

   getLocalAddr():返回web服务器的IP

   getLocalName():返回web服务器主机名

   getMethod():返回客户机请求方式

三,request获取头信息

   request.getHeader(name);//获取单个请求头name对应的value值

   request.getHeaders("Accept-Encoding");//获取多个同名请求头对应的一组value值,因此返回枚举类型数据

   request.getHeaderNames();//获取请求头的所有name值,返回的数据也是一个枚举类型的数据,将枚举中的元素依次遍历出来,根据name获取对应的value值,即可得到Http请求头的所有信息

具体操作:

/**
* 获取头信息
*/
String headValue = request.getHeader("Accept-Encoding");//获取单个请求头name对应的value值
System.out.println(headValue);


Enumeration e = request.getHeaders("Accept-Encoding");//获取多个同名请求头对应的一组value值,因此返回枚举类型数据
/**
* 将数据遍历出来
*/
while(e.hasMoreElements()){
//遍历枚举中存储的每一个元素
String value = (String)e.nextElement();
System.out.println(value);//将值输出
}

/**
* 获取所有请求头信息
*/
Enumeration er = request.getHeaderNames();//获取请求头的所有name值
while(er.hasMoreElements()){
String name =(String) er.nextElement();
String value = request.getHeader(name);
System.out.println(name+"="+value);
}

四,获取客户端请求参数

getParameter(name):获取指定名称的参数值。这是最为常用的方法之一。
getParameterValues(String name):获取指定名称参数的所有值数组。它适用于一个参数名对应多个值的情况。如页面表单中的复选框,多选列表提交的值。
getParameterNames():返回一个包含请求消息中的所有参数名的Enumeration对象。通过遍历这个Enumeration对象,就可以获取请求消息中所有的参数名
getParameterMap():返回一个保存了请求消息中的所有参数名和值的Map对象。Map对象的key是字符串类型的参数名,value是这个参数所对应的Object类型的值数组。

五,各种路径获取

request.getRealPath() 这个方法已经不推荐使用了,代替方法是:

request.getSession().getServletContext().getRealPath()

request.getSession().getServletContext().getRealPath("/"); 获取Web项目的全路径

request.getContextPath(),返回的是项目的根目录,项目放在Tomcat的ROOT下就为空,本地中如果没有配置Application context,也会返回空,反之配置了就返回配置的值

ps:Java中读取配置文件方式

方式一:采用ServletContext读取,读取配置文件的realpath,然后通过文件流读取出来。

因为是用 ServletContext读取文件路径,所以配置文件可以放入在 WEB-INFclasses目录中,也可以在 应用层级WEB-INF的目录中。
文件存放位置具体在eclipse工程中的表现是: 可以放在src下面,也可放在web-info及webroot下面等。
因为是读取出路径后,用文件流进行读取的,所以可以读取任意的配置文件包括xml和properties。 缺点:不能在servlet外面应用读取配置信息。

String realPath = getServletContext().getRealPath(path);

InputStreamReader reader =new InputStreamReader(new FileInputStream(realPath),"utf-8");

方式二:采用ResourceBundle类读取配置信息

优点是:可以以完全限定类名的方式加载资源后,直接的读取出来,且可以在非Web应用中读取资源文件。
缺点:只能加载类classes下面的资源文件,且只能读取.properties文件。

/**
     * 获取指定.properties配置文件中所以的数据
     * @param propertyName
     *        调用方式:
     *            1.配置文件放在resource源包下,不用加后缀
     *              PropertiesUtil.getAllMessage("message");
     *            2.放在包里面的
     *              PropertiesUtil.getAllMessage("com.test.message");
     * @return
     */
    public static List<String> getAllMessage(String propertyName) { // 获得资源包 ResourceBundle rb = ResourceBundle.getBundle(propertyName.trim()); // 通过资源包拿到所有的key Enumeration<String> allKey = rb.getKeys(); // 遍历key 得到 value List<String> valList = new ArrayList<String>(); while (allKey.hasMoreElements()) { String key = allKey.nextElement(); String value = (String) rb.getString(key); valList.add(value); } return valList; }

方式三:采用ClassLoader方式进行读取配置信息

优点是:可以在非Web应用中读取配置资源信息,可以读取任意的资源文件信息。
缺点:只能加载类classes下面的资源文件。

 /**获取的是classes路径下的文件
     * 优点是:可以在非Web应用中读取配置资源信息,可以读取任意的资源文件信息
     * 缺点:只能加载类classes下面的资源文件。
     * 如果要加上路径的话:com/test/servlet/jdbc_connection.properties
     */
    private static void use_classLoador(){ //获取文件流 InputStream is=TestJava.class.getClassLoader().getResourceAsStream("message.properties"); //获取文件的位置 String filePath=TestJava.class.getClassLoader().getResource("message.properties").getFile(); System.out.println(filePath); }

方法四:getResouceAsStream

XmlParserHandler.class.getResourceAsStream 与 classloader 的不同之处在于使用的是当前类的相对路径。

方法五:PropertiesLoaderUtils 工具类

Spring 提供的 PropertiesLoaderUtils 允许您直接通过基于类路径的文件地址加载属性资源。
最大的好处就是:实时加载配置文件,修改后立即生效,不必重启。

   private static void springUtil(){ Properties props = new Properties(); while(true){ try { props=PropertiesLoaderUtils.loadAllProperties("message.properties"); for(Object key:props.keySet()){ System.out.print(key+":"); System.out.println(props.get(key)); } } catch (IOException e) { System.out.println(e.getMessage()); } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }

参考:

https://www.jianshu.com/p/efdd1a526939

HttpServletRequest HttpServletResponse 接口详解

HttpServletRequest HttpServletResponse 接口详解

 

 

HttpServletRequest 接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据。同时,HttpServletRequest 接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及 IP 地址,还可以获取客户端正在使用的通信协议等信息。下表是接口 HttpServletRequest 的常用方法。

说明:HttpServletRequest 接口提供了很多的方法。

接口 HttpServletRequest 的常用方法

    法

    明

getAttributeNames()

返回当前请求的所有属性的名字集合

getAttribute(String name)

返回 name 指定的属性值

getCookies()

返回客户端发送的 Cookie

getsession()

返回和客户端相关的 session,如果没有给客户端分配 session,则返回 null

getsession(boolean create)

返回和客户端相关的 session,如果没有给客户端分配 session,则创建一个 session 并返回

getParameter(String name)

获取请求中的参数,该参数是由 name 指定的

getParameterValues(String name)

返回请求中的参数值,该参数值是由 name 指定的

getCharacterEncoding()

返回请求的字符编码方式

getContentLength()

返回请求体的有效长度

getInputStream()

获取请求的输入流中的数据

getMethod()

获取发送请求的方式,如 get、post

getParameterNames()

获取请求中所有参数的名字

getProtocol()

获取请求所使用的协议名称

getReader()

获取请求体的数据流

getRemoteAddr()

获取客户端的 IP 地址

getRemoteHost()

获取客户端的名字

getServerName()

返回接受请求的服务器的名字

getServerPath()

获取请求的文件的路径

 

HttpServletResponse

在 Servlet 中,当服务器响应客户端的一个请求时,就要用到 HttpServletResponse 接口。设置响应的类型可以使用 setContentType () 方法。发送字符数据,可以使用 getWriter () 返回一个对象。下表是接口 HttpServletResponse 的常用方法。

接口 HttpServletResponse 的常用方法

       方    法

    明

addCookie(Cookie cookie)

将指定的 Cookie 加入到当前的响应中

addHeader(String name,String value)

将指定的名字和值加入到响应的头信息中

containsHeader(String name)

返回一个布尔值,判断响应的头部是否被设置

encodeURL(String url)

编码指定的 URL

sendError(int sc)

使用指定状态码发送一个错误到客户端

sendRedirect(String location)

发送一个临时的响应到客户端

setDateHeader(String name,long date)

将给出的名字和日期设置响应的头部

setHeader(String name,String value)

将给出的名字和值设置响应的头部

setStatus(int sc)

给当前响应设置状态码

setContentType(String ContentType)

设置响应的 MIME 类型

2、一些区别细节

一、ServletRequest
 
代表一个 HTTP 请求,请求在内存中是一个对象,这个对象是一个容器,可以存放请求参数和属性。
 
1、请求对象何时被创建,当通过 URL 访问一个 JSP 或者 Servlet 的时候,也就是当调用 Servlet 的 service ()、doPut ()、doPost ()、doXxx () 方法时候的时候,执行 Servlet 的 web 服服务器就自动创建一个 ServletRequest 和 ServletResponse 的对象,传递给服务方法作为参数。
 
2、请求对象由 Servlet 容器自动产生,这个对象中自动封装了请求中 get 和 post 方式提交的参数,以及请求容器中的属性值,还有 http 头等等。当 Servlet 或者 JSP 得到这个请求对象的时候,就知道这个请求时从哪里发出的,请求什么资源,带什么参数等等。
 
3、ServletRequest 的层次结构
javax.servlet.ServletRequest 
  javax.servlet.http.HttpServletRequest
 
4、通过请求对象,可以获得 Session 对象和客户端的 Cookie。
 
5、请求需要指定 URL,浏览器根据 URL 生成 HTTP 请求并发送给服务器,请求的 URL 有一定的规范:
二、ServletResponse
 
也是由容器自动创建的,代表 Servlet 对客户端请求的响应,响应的内容一般是 HTML,而 HTML 仅仅是响应内容的一部分。请求中如果还包含其他资源会依次获取,如页面中含有图片,会进行第二个 http 请求用来获得图片内容。
相应对象有以下功能:
1、向客户端写入 Cookie
2、重写 URL
3、获取输出流对象,向客户端写入文本或者二进制数据
4、设置响应客户端浏览器的字符编码类型
5、设置客户端浏览器的 MIME 类型。

关于注入HttpServletRequest注入骨水泥好后悔死了的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于HK2没有为球衣注入HttpServletRequest、HttpServletRequest & HttpServletResponse 中 Body 的获取、HttpServletRequest HttpServletResponse 常见操作、HttpServletRequest HttpServletResponse 接口详解的相关知识,请在本站寻找。

本文标签: