master
Juergen Hoeller 10 years ago
parent 387da221c3
commit b559f15a00
  1. 16
      spring-expression/src/main/java/org/springframework/expression/TypedValue.java
  2. 11
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMappingJacksonResponseBodyAdvice.java
  3. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/JsonViewResponseBodyAdvice.java
  4. 9
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyAdvice.java
  5. 69
      spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java

@ -20,9 +20,9 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.ObjectUtils;
/**
* Encapsulates an object and a type descriptor that describes it.
* The type descriptor can hold generic information that would not be
* accessible through a simple {@code getClass()} call on the object.
* Encapsulates an object and a {@link TypeDescriptor} that describes it.
* The type descriptor can contain generic declarations that would not
* be accessible through a simple {@code getClass()} call on the object.
*
* @author Andy Clement
* @author Juergen Hoeller
@ -39,8 +39,8 @@ public class TypedValue {
/**
* Create a TypedValue for a simple object. The type descriptor is inferred
* from the object, so no generic information is preserved.
* Create a {@link TypedValue} for a simple object. The {@link TypeDescriptor}
* is inferred from the object, so no generic declarations are preserved.
* @param value the object value
*/
public TypedValue(Object value) {
@ -49,7 +49,8 @@ public class TypedValue {
}
/**
* Create a TypedValue for a particular value with a particular type descriptor.
* Create a {@link TypedValue} for a particular value with a particular
* {@link TypeDescriptor} which may contain additional generic declarations.
* @param value the object value
* @param typeDescriptor a type descriptor describing the type of the value
*/
@ -80,9 +81,10 @@ public class TypedValue {
return false;
}
TypedValue otherTv = (TypedValue) other;
// Avoid TypeDescriptor initialization if not necessary
return (ObjectUtils.nullSafeEquals(this.value, otherTv.value) &&
((this.typeDescriptor == null && otherTv.typeDescriptor == null) ||
getTypeDescriptor().equals(otherTv.getTypeDescriptor())));
ObjectUtils.nullSafeEquals(getTypeDescriptor(), otherTv.getTypeDescriptor())));
}
@Override

@ -33,13 +33,7 @@ import org.springframework.http.server.ServerHttpResponse;
* @author Rossen Stoyanchev
* @since 4.1
*/
public abstract class AbstractMappingJacksonResponseBodyAdvice
implements ResponseBodyAdvice<Object> {
protected AbstractMappingJacksonResponseBodyAdvice() {
}
public abstract class AbstractMappingJacksonResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
@ -61,7 +55,7 @@ public abstract class AbstractMappingJacksonResponseBodyAdvice
* additional serialization instructions) or simply cast it if already wrapped.
*/
protected MappingJacksonValue getOrCreateContainer(Object body) {
return (body instanceof MappingJacksonValue) ? (MappingJacksonValue) body : new MappingJacksonValue(body);
return (body instanceof MappingJacksonValue ? (MappingJacksonValue) body : new MappingJacksonValue(body));
}
/**
@ -70,5 +64,4 @@ public abstract class AbstractMappingJacksonResponseBodyAdvice
protected abstract void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType,
MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response);
}

@ -35,12 +35,10 @@ import org.springframework.util.Assert;
*
* @author Rossen Stoyanchev
* @since 4.1
*
* @see com.fasterxml.jackson.databind.ObjectMapper#writerWithView(Class)
*/
public class JsonViewResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return (super.supports(returnType, converterType) && returnType.getMethodAnnotation(JsonView.class) != null);

@ -40,28 +40,25 @@ public interface ResponseBodyAdvice<T> {
/**
* Whether this component supports the given controller method return type
* and the selected {@code HttpMessageConverter} type.
*
* @param returnType the return type
* @param converterType the selected converter type
* @return {@code true} if beforeBodyWrite should be invoked, {@code false} otherwise
* @return {@code true} if {@link #beforeBodyWrite} should be invoked, {@code false} otherwise
*/
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
/**
* Invoked after an {@code HttpMessageConverter} is selected and just before
* its write method is invoked.
*
* @param body the body to be written
* @param returnType the return type of the controller method
* @param selectedContentType the content type selected through content negotiation
* @param selectedConverterType the converter type selected to write to the response
* @param request the current request
* @param response the current response
*
* @return the body that was passed in or a modified, possibly new instance
*/
T beforeBodyWrite(T body, MethodParameter returnType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response);
}

@ -90,12 +90,22 @@ public abstract class AbstractSockJsService implements SockJsService {
/**
* A unique name for the service mainly for logging purposes.
* A scheduler instance to use for scheduling heart-beat messages.
*/
public TaskScheduler getTaskScheduler() {
return this.taskScheduler;
}
/**
* Set a unique name for this service (mainly for logging purposes).
*/
public void setName(String name) {
this.name = name;
}
/**
* Return the unique name associated with this service.
*/
public String getName() {
return this.name;
}
@ -121,8 +131,7 @@ public abstract class AbstractSockJsService implements SockJsService {
}
/**
* The URL to the SockJS JavaScript client library.
* @see #setSockJsClientLibraryUrl(String)
* Return he URL to the SockJS JavaScript client library.
*/
public String getSockJsClientLibraryUrl() {
return this.clientLibraryUrl;
@ -132,7 +141,7 @@ public abstract class AbstractSockJsService implements SockJsService {
* Streaming transports save responses on the client side and don't free
* memory used by delivered messages. Such transports need to recycle the
* connection once in a while. This property sets a minimum number of bytes
* that can be send over a single HTTP streaming request before it will be
* that can be sent over a single HTTP streaming request before it will be
* closed. After that client will open a new request. Setting this value to
* one effectively disables streaming and will make streaming transports to
* behave like polling transports.
@ -142,6 +151,10 @@ public abstract class AbstractSockJsService implements SockJsService {
this.streamBytesLimit = streamBytesLimit;
}
/**
* Return the minimum number of bytes that can be sent over a single HTTP
* streaming request before it will be closed.
*/
public int getStreamBytesLimit() {
return this.streamBytesLimit;
}
@ -168,32 +181,28 @@ public abstract class AbstractSockJsService implements SockJsService {
}
/**
* Whether JSESSIONID cookie is required for the application to function. For
* more detail see {@link #setSessionCookieNeeded(boolean)}.
* Return whether the JSESSIONID cookie is required for the application to function.
*/
public boolean isSessionCookieNeeded() {
return this.sessionCookieNeeded;
}
/**
* The amount of time in milliseconds when the server has not sent any
* messages and after which the server should send a heartbeat frame to the
* client in order to keep the connection from breaking.
* Specify the amount of time in milliseconds when the server has not sent
* any messages and after which the server should send a heartbeat frame
* to the client in order to keep the connection from breaking.
* <p>The default value is 25,000 (25 seconds).
*/
public void setHeartbeatTime(long heartbeatTime) {
this.heartbeatTime = heartbeatTime;
}
public long getHeartbeatTime() {
return this.heartbeatTime;
}
/**
* A scheduler instance to use for scheduling heart-beat messages.
* Return the amount of time in milliseconds when the server has not sent
* any messages.
*/
public TaskScheduler getTaskScheduler() {
return this.taskScheduler;
public long getHeartbeatTime() {
return this.heartbeatTime;
}
/**
@ -214,12 +223,12 @@ public abstract class AbstractSockJsService implements SockJsService {
}
/**
* The number of server-to-client messages that a session can cache while waiting for
* the next HTTP polling request from the client. All HTTP transports use this
* The number of server-to-client messages that a session can cache while waiting
* for the next HTTP polling request from the client. All HTTP transports use this
* property since even streaming transports recycle HTTP requests periodically.
* <p>The amount of time between HTTP requests should be relatively brief and will not
* exceed the allows disconnect delay (see
* {@link #setDisconnectDelay(long)}), 5 seconds by default.
* <p>The amount of time between HTTP requests should be relatively brief and will
* not exceed the allows disconnect delay (see {@link #setDisconnectDelay(long)});
* 5 seconds by default.
* <p>The default size is 100.
*/
public void setHttpMessageCacheSize(int httpMessageCacheSize) {
@ -234,7 +243,7 @@ public abstract class AbstractSockJsService implements SockJsService {
}
/**
* Some load balancers don't support WebSocket. This option can be used to
* Some load balancers do not support WebSocket. This option can be used to
* disable the WebSocket transport on the server side.
* <p>The default value is "true".
*/
@ -243,8 +252,7 @@ public abstract class AbstractSockJsService implements SockJsService {
}
/**
* Whether WebSocket transport is enabled.
* @see #setWebSocketEnabled(boolean)
* Return whether WebSocket transport is enabled.
*/
public boolean isWebSocketEnabled() {
return this.webSocketEnabled;
@ -252,9 +260,8 @@ public abstract class AbstractSockJsService implements SockJsService {
/**
* {@inheritDoc}
* <p>This method determines the SockJS path and handles SockJS static URLs. Session
* URLs and raw WebSocket requests are delegated to abstract methods.
* This method determines the SockJS path and handles SockJS static URLs.
* Session URLs and raw WebSocket requests are delegated to abstract methods.
*/
@Override
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
@ -271,7 +278,6 @@ public abstract class AbstractSockJsService implements SockJsService {
if (logger.isTraceEnabled()) {
logger.trace(request.getMethod() + " with SockJS path [" + sockJsPath + "]");
}
try {
request.getHeaders();
}
@ -309,7 +315,6 @@ public abstract class AbstractSockJsService implements SockJsService {
String serverId = pathSegments[0];
String sessionId = pathSegments[1];
String transport = pathSegments[2];
if (!validateRequest(serverId, sessionId, transport)) {
response.setStatusCode(HttpStatus.NOT_FOUND);
return;
@ -336,7 +341,7 @@ public abstract class AbstractSockJsService implements SockJsService {
}
if (!isWebSocketEnabled() && transport.equals("websocket")) {
logger.debug("Ignoring WebSocket request (transport disabled via SockJsService property).");
logger.debug("Ignoring WebSocket request (transport disabled via SockJsService property)");
return false;
}
@ -360,7 +365,6 @@ public abstract class AbstractSockJsService implements SockJsService {
protected void addCorsHeaders(ServerHttpRequest request, ServerHttpResponse response, HttpMethod... httpMethods) {
HttpHeaders requestHeaders = request.getHeaders();
HttpHeaders responseHeaders = response.getHeaders();
try {
// Perhaps a CORS Filter has already added this?
if (!CollectionUtils.isEmpty(responseHeaders.get("Access-Control-Allow-Origin"))) {
@ -373,8 +377,7 @@ public abstract class AbstractSockJsService implements SockJsService {
}
String origin = requestHeaders.getFirst("origin");
origin = ((origin == null) || origin.equals("null")) ? "*" : origin;
origin = (origin == null || origin.equals("null") ? "*" : origin);
responseHeaders.add("Access-Control-Allow-Origin", origin);
responseHeaders.add("Access-Control-Allow-Credentials", "true");

Loading…
Cancel
Save