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;
}
}
Related
My handler was working prior to some dependency updates and ditching of the XML in my app. But now I get this error
org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping for GET /resources/img/logo.png
My view resolver is working fine, my controller is pointing to the right places it is just my css/js that doesn't seem to map.
public class ConfigClass {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
WebMvcConfigurationSupport appears to be essential.
public class ConfigClass extends WebMvcConfigurationSupport{
//Rest here
}
EDIT
The initial answer was based on an amateur "cached" answer. The actual solution was using
public class ConfigClass extends WebMvcConfigurerAdapter {
However, this is now deprecated. Am looking into an answer for that.
My application is working well, but I´m not sure why I needed to configure the way I did.
The issue is that transactions must be enabled in both contexts, root and dispatcher.
Why is this necessary?
The app is configured like this:
public class MvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses () {
return new Class<?>[] {RootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses () {
return new Class<?>[] {WebMvcConfig.class};
}
}
Then
#Configuration
#Import(value = {
DataSourceConfig.class,
JpaConfig.class,
SecurityConfig.class
})
#ComponentScan(
basePackages = {"com.**.service", "com.**.mail", "com.core.config"},
excludeFilters = {
#Filter(Configuration.class),
#Filter(Controller.class),
#Filter(RestController.class)
})
#EnableAsync
#EnableScheduling
#EnableAspectJAutoProxy
#EnableTransactionManagement
public class RootConfig {
// Beans Config...
}
Finally
#Configuration
#ComponentScan(basePackages = {"com.web"})
#EnableWebMvc
#EnableTransactionManagement
public class WebMvcConfig extends WebMvcConfigurerAdapter {
// Beans Config ...
}
Note:
Transactions are just managed in the Service Layer.
That #EnableTransactionManagement is present in both config
classes.
If I remove the one in WebMvcConfig, transactions will not be injected in the service layer when accesed from a Controller class. Even though the service layer is scanned by the root context.
If I remove the one in RootConfig, transactions will not be injected in the service layer when accesed for example by Spring Security.
Is there any way to enable transactions globally?
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!
In the following setup, the TimingInterceptor and CORSHeaders interceptor execute on all URL requests, except for /resources/** URLs. How do I make the interceptors work for /resources/** URLs served by the ResourceHttpRequestHandler?
#EnableWebMvc //equivalent to mvc:annotation-driven
#Configuration
#PropertySource("classpath:configuration.properties")
public class WebConfig extends WebMvcConfigurerAdapter {
#Inject
private TimingInterceptor timingInterceptor;
#Inject
private CORSHeaders corsHeaders;
// equivalent to mvc:resources
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
// equivalent to mvc:interceptors
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timingInterceptor).addPathPatterns("/**");
registry.addInterceptor(corsHeaders).addPathPatterns("/**");
}
}
Update: As of Spring Framework 5.0.1 (and SPR-16034), interceptors are automatically mapped on ResourceHttpRequestHandler by default.
I think the configured interceptors aren't mappped on the resource handler, but on the one handling #RequestMapping requests.
Maybe try this instead?
#EnableWebMvc //equivalent to mvc:annotation-driven
#Configuration
#PropertySource("classpath:configuration.properties")
public class WebConfig extends WebMvcConfigurerAdapter {
#Inject
private TimingInterceptor timingInterceptor;
#Inject
private CORSHeaders corsHeaders;
// equivalent to mvc:resources
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public MappedInterceptor timingInterceptor() {
return new MappedInterceptor(new String[] { "/**" }, timingInterceptor);
}
#Bean
public MappedInterceptor corsHeaders() {
return new MappedInterceptor(new String[] { "/**" }, corsHeaders);
}
}
This should be better documented with SPR-10655.
I never tried to use Spring interceptors for serving resources. The power of interceptors is to have a hook before controller and between controller and view.
To add pre- or post-processing around resources, you'd better use filters.
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);
}