How to set content-type correctly in thymeleaf when mixing html and json templates - spring

I'm working on a single page application using spring boot and thymeleaf. I have two kinds of templates; one producing the SPA scaffolding page as html and multiple producing json responses.
The json responses are being sent back with a content-type of text/html when I would like them to be application/json.
How do I have the content-types set correctly? Do I need two thymeleaf view resolvers? I tried #GetMapping(value = Routes.EVENTS, produces = MediaType.APPLICATION_JSON_VALUE) on the #Controller but to no effect.

I'm sure there are a few approaches to solving this. Here is the one that worked for me.
I figured it out by looking in the Spring Boot documentation on custom view resolvers. This lead me to looking at the ThymeleafAutoConfiguration class. Then a bit of judicious debugging in the Spring framework helped to fill in the gaps.
#Bean
public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setContentType("application/json");
viewResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {"*.json"});
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}

Related

How can I set http method in servlet filter(in context of Spring Framework)?

I have got a such issue: I do have got antMatcher​ in Spring Security. And I have an opportunity to set http method GET/POST/PUT/PATCH/DELETE for url mapping for my filter. So requests with some methods will be filtered with my filter if they have certain methods and will not be filtered otherways. But how can I specify http method without Spring Security? Is it possible to do it somehow in a cool way using FilterRegistrationBean or I will be have to use
switch(request.getMethod()) {
...
}
in my fileter doFilterInternal() method (I use OncePerRequestFilter) and act according to which method is specified in HttpServletRequest? That is tedious, isn`t it?
I tried to find out some info according to this issue and researches have not been successful yet.
#Bean
public FilterRegistrationBean<CustomFilter> registrationBean(){
FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(customFilter);
registration.addUrlPatterns("/open/*");
/*may be it is possible to addHttpMethods?*/
registration.setName("customLoggingFilter");
registration.setOrder(2);
return registration;
}
Well, no. It is impossible, but I was told that it is a really not bad idea to override the shouldFilter method of the OncePerRequestFilter.

Swagger for spring boot describing parameter

My question is pretty simple:
having rest controller's params like
( #RequestBody Wrapper<Request> requestBody){...}
i got to customize UI view of model Wrapper<Request>. It has some fields and I use it from different starter. Im able to put #Schema(required=true) on the field of Request, cause it's located in my module, but what about Wrapper ? Thx.
This is related to #1490.The way to configure this is to create a
custom alternateTypeRules in the Docket config. For e.g. if you have
an immutable MyClass that generates ImmutableMyClass, then we would
add a rule for it as shown below.
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.alternateTypeRules(AlternateTypeRules.newRule(MyClass.class,
ImmutableMyClass.class));
https://springfox.github.io/springfox/docs/snapshot/#answers-to-common-questions-and-problems , see #22. It has side effects like resetting all custom settings.

Spring data rest how to serve hal+json serialization for content-type json

We are using spring-data-rest to expose our repositories.
Choosing as default type application/hal+json produce the desired presentation of the resources and links, with content exposed as _embedded and links as _links.
Unfortunately, Firefox is not able to render application/hal+json, suggesting user to download the hal+json document if the user is navigating the api using the browser.
As a possible solution to this, we would like to support application/json as defaultMediaType and also hal+json if the user is explicitly requiring that.
Using application/json as defaultMediaType with spring-data-rest tough bypass the hal+json serialization provided by spring-hateoas, so the resources are displayed with "content" and "links".
I've tried to extends the RepositoryRestConfigurerAdapter, overriding the configureHttpMessageConverter this way
#Override
public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jackson2HalModule());
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class);
halConverter.setObjectMapper(mapper);
halConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaTypes.HAL_JSON));
//make sure this is inserted first
messageConverters.add(0, halConverter);
super.configureHttpMessageConverters(messageConverters);
}
but the converter is not used to render the resources.
Any one has any suggestion on how to tackle this?

Usage of different ViewResolver in Spring Mvc

I am a beginner in spring-mvc. While going through the view resolvers, I am able to understand that how to use following view resolvers:
BeanNameViewResolver,InternalResourceViewResolver and
UrlBasedViewResolver
I have already gone through the google to understand but still i am not clear about their pros and cons over each other.
How one should decide when to use which view Resolver.
If someone can help me in understanding that,it would be a great help.
Thanks,
InternalResourceViewResolver is a subclass of UrlBasedViewResolver.
UrlBasedViewResolver and InternalResourceViewResolver are often used in MVC application where the controller return the name of the view that should been rendered. The controller return an logical name of the view, and the resolver made it a file name (of the jsp), by adding some pre - and postfix. For example: logical view name return by the controller: main/example, prefix: /WEB-INF/pages/, postfix: .jsp -> /WEB-INF/pages/main/example.jsp gets rendered with the model-data provided by the controller
The UrlBasedViewResolver needs a View class (like the most other ViewResolvers too). (very brif: The view class is responsible for rendering, while the resolver is responsible to pick the right template/...) The view used in UrlBasedViewResolver has to be an subclass of AbstractUrlBasedView.
The InternalResourceViewResolver is convenient subclass of UrlBasedViewResolver that has be default already a configured view: InternalResourceView (or JstlView when Jstl is present). So it is the right resolver when JSPs are used as template engine.
There are other AbstractUrlBasedView implementations, for example for JasperReports, Freemaker, Velocity, Tiles, .... Most of them has a convenient subclass of UrlBasedViewResolver too.
BeanNameViewResolver very very old resolvers, from the old Spring 2.0 time. At this time each controller was for handling one URL. At this time there was no #RequestMapping annotation, and one has to tell Spring which controller was for which url. One could list them all, or have this Resolver, that was able to map url->controller by the controller name. Since Spring 3.0 (more exact since 2.5) and Springs annotation support, this resolver is used very rarely.
When your Spring application loads there is default ViewResolver that gets loaded - InternalResourceViewResolver. You can refer to the default beans that gets initialized in DisplacherServlet.properties in spring-webmvc jar In case of View Resolvers it is -
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
which essentially returns a JSTL view.
There are lot of URLBasedViewResolvers like -
InternalResourceViewResolver
VelocityViewReolver
FreeMarkerViewReolver
ThymeleafViewResolver
XsltViewReolver
Yup you read it right. InternalResourceViewResolver is a convenient subclass of UrlBasedViewResolver.
If you want to know more about these View Resolvers see - http://www.studytrails.com/frameworks/spring/spring-mvc-view-resolver.jsp
NOTE : Important point to note in case of chaining of view resolvers. In the chain Spring moves on to next View resolver only if current View resolver returns null. Some URLBasedViewResolvers (Tiles, Velocity,Freemarker) check if resource exist and return null. So they can be anywhere in the view resolver chain. Others must be last (JSTL/JSP, XSLT, JSON)

Handling JSON and form data request with Spring MVC

I'm working on simple Spring-MVC application and I love new Spring REST features. I'd like to use the same method to process regular form and JSON data. It seems to be a little tricky, however. For example, method
public #ResponseBody String process(#RequestBody Bean bean);
will work for JSON request (Content-type: application/json), and
public #ResponseBody String process(Bean bean);
will match request with Content-type: application/x-www-form-urlencoded.
These methods are obviously will have almost the same content, so I'd prefer to avoid such duplication. With Jersey it's possible with #Consumes annotations, but I can't figure out how to do it with Spring.
First, the above declaration won't compile, because you are having duplicate signature.
Btw, #Consumes wouldn't help, I think, because it only designates what content type the method can handle.
In spring you can specify the content-type with
#RequestMapping(headers="Content-Type=application/json")
Just add #RestController annotation for the controller class.

Resources