SpringBoot - UTF8 & Controller - spring-mvc

I am using SpringBoot and Spring MVC for my Web Application and when I submit any form my controller gets the information encoded with ISO-8859-1 instead of UTF-8.
My application.properties
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost/pfg
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.sqlScriptEncoding=UTF-8
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes=true
spring.messages.encoding=UTF-8
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
I also have this ServerInitializer class:
#Configuration
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PfgApplication.class);
}
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return filter;
}
}
Thanks for the help.

Are you using 1.3.0.M5 by chance? In that case there's a bug and you might want to consider using the workaround:
https://github.com/spring-projects/spring-boot/issues/3912
#Autowired
private HttpEncodingProperties httpEncodingProperties;
#Bean
public OrderedCharacterEncodingFilter characterEncodingFilter() {
OrderedCharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.httpEncodingProperties.getCharset().name());
filter.setForceEncoding(this.httpEncodingProperties.isForce());
filter.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filter;
}

for Example
#RequestMapping(value="/user", **produces="text/html;charset=UTF-8"**)
public class UserController{
}
add blackbody part is ok!

Related

How do I using RedisMessageListenerContainer in configuration class

I am using spring-MVC and spring-data-redis to control Redis-cluster pool.
When I using jedisCluster.subscribe(new JedisPubSubListener(), "bb");
my application will stock in this code(I try to use thread but the other one can't get the instance in #autowerid).
I google a lot of way point me to using spring-boot .
but I can change the structure in our project.
So I think when spring init I can register a listener to use.
But I can run sauce in my original code.
Can someone make an example for me if I using this following code :
#Configuration
public class RedisClusterConfig {
private List<String> redisNodes(){
return Arrays.asList(redisNode.split(","));
}
#Bean
JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
jedisPoolConfig.setTestOnReturn(testOnReturn);
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
#Bean
RedisConnectionFactory redisClusterConnectionFactory(JedisPoolConfig
jedisPoolConfig){
JedisConnectionFactory redisConnectionFactory = new
JedisConnectionFactory(new RedisClusterConfiguration(redisNodes()));
redisConnectionFactory.setPoolConfig(jedisPoolConfig);
return redisConnectionFactory;
}
}
this is how I setting in my configuration.
#Bean
public RedisMessageListenerContainer redisMessageListenerContainer() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(consumerRedis(),topic());
return container;
}
#Bean
public ConsumerRedisListener consumerRedis() {
return new ConsumerRedisListener();//this class implements MessageListener
}
#Bean
public ChannelTopic topic() {
return new ChannelTopic("channel");
}

Hide/remove Spring MVC endpoint in Swagger2

I'm using Swagger 2 for API UI. So, my gradle.build has:
compile "io.springfox:springfox-swagger2:${swaggerVersion}"
compile "io.springfox:springfox-swagger-ui:${swaggerVersion}"
I've configured Swagger as below:
#Configuration
#Profile("!production")
#EnableSwagger2
#ComponentScan(basePackageClasses = com.company.controllers.ContentController.class)
public class SwaggerConfiguration {
#Autowired
private BuildInfo buildInfo;
#Bean
public Docket awesomeApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(this.awesomeApiInfo())
.select()
.apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
.build();
}
private ApiInfo awesomeApiInfo() {
return new ApiInfoBuilder()
.title("Awesome API - build #" + this.buildInfo.getVersion())
.description("Enter the IDs in order to look for the content")
.version("0.1")
.build();
}
}
I'm getting the api endpoint that I have defined, but also getting the Spring MVC endpoints as below:
Now, I need to get rid of these mvc endpoints.
Any help is highly appreciated!!
Ohhh... actually it was my silly mistake. I changed RequestHandlerSelectors to select only endpoints from my own controller package as follow:
#Bean
public Docket awesomeApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(this.awesomeApiInfo())
.select()
.paths(PathSelectors.any())
.apis(RequestHandlerSelectors.basePackage("com.company.awesome.controllers"))
.build();
}
And this shows only the endpoints mapped within the classes in controller package.
The best approach you can follow is to restrict visibility and access to ServiceStack. So you can hide it from being visible externally with:
[Restrict(VisibleInternalOnly = true)]
public class InternalAdmin { }
you can read more about it here
An alternative to specifying base package is to create a class annotation like this:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface SwaggerDocumentation {
}
and then once defined use it on your Controller as desired:
#RestController
#SwaggerDocumentation
public class EntityRestController {
EntityService entityService;
#Autowired
public EntityRestController(final EntityService entityService) {
this.entityService = entityService;
}
#GetMapping("/status")
String getTest() {
return "Ready";
}
#GetMapping("/api/entities")
Collection<Entity> getEntities() {
return entityService.findSome();
}
}
and then finally in the SwaggerConfig class
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(SwaggerDocumentation.class))
.build();
}
}

Reconfigure Spring Data Rest to Index at Page 1

I thought I had this figured out but the setting does not seem to change the index. setOneIndexedParameters(true)
#Configuration
#EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
resolver.setOneIndexedParameters(true);
argumentResolvers.add(resolver);
super.addArgumentResolvers(argumentResolvers);
}
.... other config stuff
Expected result is that instead of the base URL for spring data rest being http://localhost:8080/api/text?page=0&size=20 it would change to http://localhost:8080/api/text?page=1&size=20 as the initial page.
Did I do this correctly or is this a bug?
The answer was here Spring Data Rest - Configure pagination
I moved the configuration to extending RepositoryRestMvcConfiguration
#Configuration
class CustomRestMvcConfiguration extends RepositoryRestMvcConfiguration {
#Override
#Bean
public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
HateoasPageableHandlerMethodArgumentResolver resolver = super.pageableResolver();
resolver.setOneIndexedParameters(true);
return resolver;
}
}

How to set context-param in spring-boot

In the classic web.xml type configuration you could configure context parameters like so
web.xml
...
<context-param>
<param-name>p-name</param-name>
<param-value>-value</param-value>
</context-param>
...
How is this achieved in spring-boot. I have a filter that requires parameters.
I'm using #EnableAutoConfiguration and have included <artifactId>spring-boot-starter-jetty</artifactId> in my pom.
You can set parameters using the server.servlet.context-parameters application property. For example:
server.servlet.context-parameters.p-name=p-value
In Spring Boot 1.x, which is no longer supported, this property was named server.context-parameters:
servlet.context-parameters=p-name=p-value
Alternatively, you can configure parameters programmatically by declaring a ServletContextInitializer bean:
#Bean
public ServletContextInitializer initializer() {
return new ServletContextInitializer() {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("p-name", "-value");
}
};
}
You can actually achieve this using Java config. If you have filter that requires some parameters, just put them in your application.yml (or .properties), inject them using #Value in your config class and register them in FilterRegistrationBean.
For example:
#Value("${myFilterParam}")
private String myFilterParam;
#Bean(name="myFilter")
public FilterRegistrationBean myFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.setInitParameters(Collections.singletonMap("p-name", "p-value"));
return filterRegistrationBean;
}
Also JavaDoc for FilterRegistrationBean:
http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/embedded/FilterRegistrationBean.html
Update
You can register parameters for servlet context in SpringBootServletInitializer#onStartup() method. Your Application class can extend the SpringBootServletInitializer and you can override the onStartup method and set the parameters there. Example:
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("p-name", "p-value");
super.onStartup(servletContext);
}
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
Other alternative is to define ServletContextInitializer bean as suggested by Andy Wilkinson.
Since Spring Boot 2.0.0 they updated the way to add context param:
server.servlet.context-parameters.yourProperty.
You can see more updates on this link
Also you can define InitParameterConfiguringServletContextInitializer in your configuration. Example:
#Bean
public InitParameterConfiguringServletContextInitializer initParamsInitializer() {
Map<String, String> contextParams = new HashMap<>();
contextParams.put("p-name", "-value");
return new InitParameterConfiguringServletContextInitializer(contextParams);
}

Spring MVC jackson auto serialize?

I would like to serialize an object with jackson in spring MVC.
I have a controller which returns an ObjectTest1 which has a property ObjectTest2.
public class ObjectTest1{
private ObjectTest2;
// setters getters...
}
public class ObjectTest2{
private String value;
// setters getters...
}
public #ResponseBody ObjectTest1 test() throws IOException ...
I have a mapper and I have a serializer for ObjectTest2 and I've annotated the ObjectTest1.getObjectTest2 method with #JsonSerialize(using = ObjectTest2.class).
It works correctly!
But I want to use this serializer in a lot of Object, not just in ObjectTest1.
What should I do to avoid put annotation every getter method? Can use spring this serializer automatically for all properites which is ObjectTest2?
UPDATED:
I've already use this in my code:
<mvc:annotation-driven>
In ajax response Objects generated correctly as json.
Maybe I should try to explain another way.
So.
I have these objects:
public class DTO{
private InnerThing innerThing;
#JsonSerialize(using=ThingSerializer.class)
public InnerThing getThing(){...}
}
public class InnerThing{
private String value;
}
Generated json looks like:
{"innerThing":{"value":"something"}}
Afther when I've written a serializer, json is:
{"innerThing":"something"}
It is OK, but to get the second version of json I must annotate the getInnerThing method in DTO class with #JsonSerialize...
I don't want to annotate all methods where I use InnerThing as a property.
So my question is, can spring auto serialize every property which type is InnerThing?
By default, Spring will handle serialization and de-serialization of JSON automatically if you add Jackson to the classpath and you use either <mvc:annotation-driven> or #EnableWebMvc.
Links to the Spring Reference Docs:
Spring 3.0: <mvc:annotation-driven>
Spring 3.1: <mvc:annotation-driven> and #EnableWebMvc
You want Jackson to always use your custom JsonSerializer or JsonDeserializer to serialize/deserialize a specific type?
I ended up writing a custom Jackson module to let Jackson find serializers and deserializers that are Spring beans.
I am using Spring 3.1.2 and Jackson 2.0.6
Simplified version:
public class MyObjectMapper extends ObjectMapper {
#Autowired
public MyObjectMapper(ApplicationContext applicationContext) {
SpringComponentModule sm = new SpringComponentModule(applicationContext);
registerModule(sm);
}
}
Module:
public class SpringComponentModule extends Module {
private ApplicationContext applicationContext;
public SpringComponentModule(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override public String getModuleName() {
return "jackson-spring-component";
}
#Override public Version version() {
return SpringComponentModuleVersion.instance.version();
}
#Override
public void setupModule(SetupContext context) {
context.addSerializers(new SpringComponentSerializers(this.applicationContext));
context.addDeserializers(new SpringComponentDeserializers(this.applicationContext));
}
}
ComponentSerializer class:
public class SpringComponentSerializers extends Serializers.Base {
private ApplicationContext applicationContext;
public SpringComponentSerializers(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) {
Class<?> raw = type.getRawClass();
Map<String,JsonSerializer> beanSet = applicationContext.getBeansOfType(JsonSerializer.class);
for(String beanName : beanSet.keySet()) {
JsonSerializer<?> serializer = beanSet.get(beanName);
if(serializer.handledType().isAssignableFrom(raw)) {
return serializer;
}
}
return null;
}
}

Resources