Skip to content

Commit

Permalink
Feature/springboot (#3)
Browse files Browse the repository at this point in the history
Added a new catnap-springboot module to address Issue #2
  • Loading branch information
gregwhitaker authored Sep 22, 2016
1 parent c6bd9cf commit 7cabdc3
Show file tree
Hide file tree
Showing 19 changed files with 591 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ As you can see the partial response is a significant reduction in payload size a
##Getting Catnap
Catnap libraries are available from JCenter.

* [catnap-spring](https://bintray.com/gregwhitaker/maven/catnap-spring) - Use this library if you are integrating Catnap with a SpringMVC or Spring Boot application.
* [catnap-spring](https://bintray.com/gregwhitaker/maven/catnap-spring) - Use this library if you are integrating Catnap with a SpringMVC.
* [catnap-springboot](https://bintray.com/gregwhitaker/maven/catnap-springboot) - Use this library if you are integrating Catnap with Spring Boot.
* [catnap-jaxrs](https://bintray.com/gregwhitaker/maven/catnap-jaxrs) - Use this library if you are integrating Catnap with a Jersey or RESTEasy application.

##Getting Started with Catnap
Expand Down
9 changes: 9 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,12 @@ project(":catnap-spring") {
maven { url "https://repo.spring.io/milestone" }
}
}

project(":catnap-springboot") {
ext.artifact = 'catnap-springboot'

repositories {
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
}
2 changes: 1 addition & 1 deletion catnap-examples/catnap-examples-springboot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repositories {
}

dependencies {
compile 'com.github.gregwhitaker:catnap-spring:2.0.0'
compile project(":catnap-springboot")

compile('org.springframework.boot:spring-boot-starter-web')
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package catnap.examples.springboot;

import com.github.gregwhitaker.catnap.springmvc.annotation.EnableCatnap;
import com.github.gregwhitaker.catnap.springboot.annotation.EnableCatnap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import catnap.examples.springboot.model.Widget;
import catnap.examples.springboot.service.WidgetService;
import com.github.gregwhitaker.catnap.core.annotation.CatnapDisabled;
import com.github.gregwhitaker.catnap.springmvc.annotation.CatnapResponseBody;
import com.github.gregwhitaker.catnap.springboot.annotation.CatnapResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down
2 changes: 2 additions & 0 deletions catnap-springboot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
catnap-springboot
===
27 changes: 27 additions & 0 deletions catnap-springboot/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'java'

apply from: file('../gradle/codequality.gradle')
apply from: file('../gradle/release.gradle')
apply from: file('../gradle/convention.gradle')

apply plugin: 'io.spring.dependency-management'

dependencyManagement {
imports {
mavenBom "io.spring.platform:platform-bom:2.0.4.RELEASE"
}
}

dependencies {
compile project(':catnap-core')

compile('org.springframework:spring-webmvc')
compile('commons-io:commons-io:2.5')
compile('org.slf4j:slf4j-api:1.7.21')
compile('commons-logging:commons-logging:1.2')

testCompile('org.springframework:spring-test')
testCompile('junit:junit:4.12')
testCompile('org.hamcrest:hamcrest-all:1.3')
testCompile('org.mockito:mockito-all:1.10.19')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.annotation;

import com.github.gregwhitaker.catnap.core.annotation.CatnapAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@CatnapAnnotation
public @interface CatnapResponseBody {

/**
* Optional argument that defines the name of the desired
* object in the returned model you wish to have rendered
* by Catnap. If a value is not supplied the class name
* of the return type of the annotated method will be
* used.
*/
public String value() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.annotation;

import com.github.gregwhitaker.catnap.core.annotation.CatnapAnnotation;
import com.github.gregwhitaker.catnap.springboot.config.CatnapWebMvcConfigurerAdapter;
import org.springframework.context.annotation.Import;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@CatnapAnnotation
@Import({CatnapWebMvcConfigurerAdapter.class})
public @interface EnableCatnap {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.config;

import com.github.gregwhitaker.catnap.springboot.messageconverters.CatnapJsonMessageConverter;
import com.github.gregwhitaker.catnap.springboot.messageconverters.CatnapJsonpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
public class CatnapWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.mediaType("json", MediaType.APPLICATION_JSON);
configurer.mediaType("jsonp", new MediaType("application", "x-javascript"));
}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new CatnapJsonMessageConverter());
converters.add(new CatnapJsonpMessageConverter());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.interceptor;

import com.github.gregwhitaker.catnap.core.annotation.CatnapDisabled;
import com.github.gregwhitaker.catnap.core.util.RequestUtil;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CatnapDisabledHandlerInterceptor extends HandlerInterceptorAdapter {

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
HandlerMethod method = (HandlerMethod) handler;

if (method.getMethodAnnotation(CatnapDisabled.class) != null) {
RequestUtil.disableCatnap(request);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.interceptor;

import com.github.gregwhitaker.catnap.core.exception.ViewRenderException;
import com.github.gregwhitaker.catnap.springboot.annotation.CatnapResponseBody;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.Introspector;
import java.util.List;
import java.util.Map;

public class CatnapResponseBodyHandlerInterceptor extends HandlerInterceptorAdapter {
public static final String MODEL_NAME = "catnapModel";

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
HandlerMethod method = (HandlerMethod) handler;

if (method.getMethodAnnotation(ResponseBody.class) == null) {
CatnapResponseBody annotation = method.getMethodAnnotation(CatnapResponseBody.class);

if (annotation != null) {
String modelName = modelName(annotation, method);

if (modelAndView != null) {
//Transfer the model to a well known key so that we can retrieve it in the view.
Object model = modelAndView.getModel().get(modelName);
modelAndView.getModel().put(MODEL_NAME, model);
}
}
}
}

private String modelName(CatnapResponseBody annotation, HandlerMethod method) {
if (!StringUtils.isEmpty(annotation.value())) {
return annotation.value();
} else {
if (List.class.isAssignableFrom(method.getReturnType().getParameterType())) {
String paramType = method.getReturnType().getGenericParameterType().getTypeName();
paramType = paramType.substring(paramType.lastIndexOf(".") + 1, paramType.length() - 1);
return Introspector.decapitalize(paramType) + "List";
}

if (Map.class.isAssignableFrom(method.getReturnType().getParameterType())) {
throw new ViewRenderException("Map is not a supported return type for methods annotated with " +
"@CatnapResponseBody. Please return an object or a list of objects. If you wish to return " +
"a map then you must use Catnap's standard model and view handling by removing the " +
"@CatnapResponseBody annotation.");
}

return Introspector.decapitalize(method.getReturnType().getParameterType().getSimpleName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2016 Greg Whitaker
*
* 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 com.github.gregwhitaker.catnap.springboot.messageconverters;

import com.github.gregwhitaker.catnap.core.view.JsonCatnapView;

/**
* An {@link org.springframework.http.converter.AbstractHttpMessageConverter} implementation that renders JSON
* responses with Catnap.
*/
public class CatnapJsonMessageConverter extends CatnapMessageConverter<JsonCatnapView> {

/**
* Initializes this instance of {@link CatnapJsonMessageConverter} with the default {@link JsonCatnapView}
* configured for rendering responses.
*/
public CatnapJsonMessageConverter() {
super(new JsonCatnapView.Builder().build());
}

/**
* Initializes this instance of {@link CatnapJsonMessageConverter}.
*
* @param view the {@link JsonCatnapView} to use when rendering responses within this message converter
*/
public CatnapJsonMessageConverter(JsonCatnapView view) {
super(view);
}
}
Loading

0 comments on commit 7cabdc3

Please sign in to comment.