diff --git a/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpRequest.java new file mode 100644 index 0000000000..a47735bc0c --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpRequest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import org.springframework.web.http.HttpInputMessage; +import org.springframework.web.http.HttpMethod; + +/** + * Represents a server-side HTTP request. + * + * @author Arjen Poutsma + * @since 3.0 + */ +public interface ServerHttpRequest extends HttpInputMessage { + + /** + * Returns the HTTP method of the request. + * + * @return the http method + */ + HttpMethod getMethod(); + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpResponse.java b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpResponse.java new file mode 100644 index 0000000000..b3cb770c19 --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServerHttpResponse.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import org.springframework.web.http.HttpOutputMessage; +import org.springframework.web.http.HttpStatus; + +/** + * Represents a server-side HTTP response. + * + * @author Arjen Poutsma + * @since 3.0 + */ +public interface ServerHttpResponse extends HttpOutputMessage { + + /** + * Sets the HTTP status code of the response. + * + * @param status the HTTP status + */ + void setStatusCode(HttpStatus status); + + /** + * Closes this response, freeing any resources created. + */ + void close(); + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpRequest.java new file mode 100644 index 0000000000..640d402915 --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpRequest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.util.Assert; +import org.springframework.web.http.HttpHeaders; +import org.springframework.web.http.HttpMethod; + +/** + * {@link ServerHttpRequest} implementation that is based on a {@link HttpServletRequest}. + * + * @author Arjen Poutsma + * @since 3.0 + */ +public class ServletServerHttpRequest implements ServerHttpRequest { + + private final HttpServletRequest servletRequest; + + private HttpHeaders headers; + + /** + * Constructs a new instance of the ServletHttpRequest based on the given {@link HttpServletRequest} + * + * @param servletRequest the HTTP Servlet request + */ + public ServletServerHttpRequest(HttpServletRequest servletRequest) { + Assert.notNull(servletRequest, "'servletRequest' must not be null"); + this.servletRequest = servletRequest; + } + + public HttpMethod getMethod() { + return HttpMethod.valueOf(servletRequest.getMethod()); + } + + public HttpHeaders getHeaders() { + if (headers == null) { + headers = new HttpHeaders(); + for (Enumeration headerNames = servletRequest.getHeaderNames(); headerNames.hasMoreElements();) { + String headerName = (String) headerNames.nextElement(); + for (Enumeration headerValues = servletRequest.getHeaders(headerName); + headerValues.hasMoreElements();) { + String headerValue = (String) headerValues.nextElement(); + headers.add(headerName, headerValue); + } + } + } + return headers; + } + + public InputStream getBody() throws IOException { + return servletRequest.getInputStream(); + } +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpResponse.java b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpResponse.java new file mode 100644 index 0000000000..940f12c8dd --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/web/http/server/ServletServerHttpResponse.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.util.Assert; +import org.springframework.web.http.HttpHeaders; +import org.springframework.web.http.HttpStatus; + +/** + * {@link ServerHttpResponse} implementation that is based on a {@link HttpServletResponse}. + * + * @author Arjen Poutsma + * @since 3.0 + */ +public class ServletServerHttpResponse implements ServerHttpResponse { + + private final HttpServletResponse servletResponse; + + private final HttpHeaders headers = new HttpHeaders(); + + private boolean headersWritten = false; + + /** + * Constructs a new instance of the ServletHttpResponse based on the given {@link HttpServletResponse} + * + * @param servletResponse the HTTP Servlet response + */ + public ServletServerHttpResponse(HttpServletResponse servletResponse) { + Assert.notNull(servletResponse, "'servletResponse' must not be null"); + this.servletResponse = servletResponse; + } + + public void setStatusCode(HttpStatus status) { + servletResponse.setStatus(status.value()); + } + + public HttpHeaders getHeaders() { + return headers; + } + + public OutputStream getBody() throws IOException { + writeHeaders(); + return servletResponse.getOutputStream(); + } + + private void writeHeaders() { + if (!headersWritten) { + for (Map.Entry> entry : headers.entrySet()) { + String headerName = entry.getKey(); + for (String headerValue : entry.getValue()) { + servletResponse.addHeader(headerName, headerValue); + } + } + headersWritten = true; + } + } + + public void close() { + writeHeaders(); + } +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/http/server/package.html b/org.springframework.web/src/main/java/org/springframework/web/http/server/package.html new file mode 100644 index 0000000000..6dd025201f --- /dev/null +++ b/org.springframework.web/src/main/java/org/springframework/web/http/server/package.html @@ -0,0 +1,10 @@ + + + +Contains an abstraction over server-side HTTP. This package +contains the ServerHttpRequest and +ServerHttpResponse, as well as a Servlet-based implementation of these +interfaces. + + + diff --git a/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpRequestTests.java b/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpRequestTests.java new file mode 100644 index 0000000000..3921338ac8 --- /dev/null +++ b/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpRequestTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import java.util.List; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.http.HttpHeaders; +import org.springframework.web.http.HttpMethod; + +/** + * @author Arjen Poutsma + */ +public class ServletHttpRequestTests { + + private ServletServerHttpRequest request; + + private MockHttpServletRequest mockRequest; + + @Before + public void create() throws Exception { + mockRequest = new MockHttpServletRequest(); + request = new ServletServerHttpRequest(mockRequest); + } + + @Test + public void getMethod() throws Exception { + mockRequest.setMethod("POST"); + assertEquals("Invalid method", HttpMethod.POST, request.getMethod()); + } + + @Test + public void getHeaders() throws Exception { + String headerName = "MyHeader"; + String headerValue1 = "value1"; + mockRequest.addHeader(headerName, headerValue1); + String headerValue2 = "value2"; + mockRequest.addHeader(headerName, headerValue2); + + HttpHeaders headers = request.getHeaders(); + assertNotNull("No HttpHeaders returned", headers); + assertTrue("Invalid headers returned", headers.containsKey(headerName)); + List headerValues = headers.get(headerName); + assertEquals("Invalid header values returned", 2, headerValues.size()); + assertTrue("Invalid header values returned", headerValues.contains(headerValue1)); + assertTrue("Invalid header values returned", headerValues.contains(headerValue2)); + } + + @Test + public void getBody() throws Exception { + byte[] content = "Hello World".getBytes("UTF-8"); + mockRequest.setContent(content); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + assertArrayEquals("Invalid content returned", content, result); + } +} \ No newline at end of file diff --git a/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpResponseTest.java b/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpResponseTest.java new file mode 100644 index 0000000000..c4bbbcc49e --- /dev/null +++ b/org.springframework.web/src/test/java/org/springframework/web/http/server/ServletHttpResponseTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.http.server; + +import java.util.List; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.http.HttpHeaders; +import org.springframework.web.http.HttpStatus; + +/** + * @author Arjen Poutsma + */ +public class ServletHttpResponseTest { + + private ServletServerHttpResponse response; + + private MockHttpServletResponse mockResponse; + + @Before + public void create() throws Exception { + mockResponse = new MockHttpServletResponse(); + response = new ServletServerHttpResponse(mockResponse); + } + + @Test + public void setStatusCode() throws Exception { + response.setStatusCode(HttpStatus.NOT_FOUND); + assertEquals("Invalid status code", 404, mockResponse.getStatus()); + } + + @Test + public void getHeaders() throws Exception { + HttpHeaders headers = response.getHeaders(); + String headerName = "MyHeader"; + String headerValue1 = "value1"; + headers.add(headerName, headerValue1); + String headerValue2 = "value2"; + headers.add(headerName, headerValue2); + + response.close(); + assertTrue("Header not set", mockResponse.getHeaderNames().contains(headerName)); + List headerValues = mockResponse.getHeaders(headerName); + assertTrue("Header not set", headerValues.contains(headerValue1)); + assertTrue("Header not set", headerValues.contains(headerValue2)); + } + + @Test + public void getBody() throws Exception { + byte[] content = "Hello World".getBytes("UTF-8"); + FileCopyUtils.copy(content, response.getBody()); + + assertArrayEquals("Invalid content written", content, mockResponse.getContentAsByteArray()); + } +} \ No newline at end of file