No mapping found for HTTP request in DispatcherServlet - spring-mvc

I tried to reach my jsp page and for some reason i got the error message
Hibernate: select person0_.pid as pid1_0_, person0_.age as age2_0_, person0_.city as city3_0_, person0_.gender as gender4_0_, person0_.password as password5_0_, person0_.username as username6_0_ from person person0_ order by person0_.pid
2016-10-04 13:49:53.090 WARN 13276 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound : No mapping found for HTTP request with URI [/WEB-INF/view/personform.jsp] in DispatcherServlet with name 'dispatcherServlet'
'
PersonController:
#Controller
public class PersonController {
#Autowired
private IPersonService personService;
#Autowired
private MessageSource messageSource;
#Autowired
private LocaleResolver localeResolver;
//#RequestMapping(value="personform")
public ModelAndView user(){
ModelAndView mv = new ModelAndView("personform","person",new Person());
setPageData(mv.getModelMap());
return mv;
}
Appconfig.java:
package App.config;
import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan("App")
#Import(DBConfig.class)
#EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("/WEB-INF/i18/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localeResolver(){
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("en"));
resolver.setCookieName("myLocaleCookie");
resolver.setCookieMaxAge(4800);
return resolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("mylocale");
registry.addInterceptor(interceptor);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app-resources/**").addResourceLocations("/resources/");
}
}
just in case, if it needed - build.gradle:
group 'mbti'
version '1.0-SNAPSHOT'
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-snapshot" }
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.3.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.3.3.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.31'
compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.1.1'
compile group: 'jstl', name: 'jstl', version: '1.2'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '1.3.3.RELEASE'
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-el', version: '8.0.32'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}

In your controller, uncomment the #requestMapping annotation and set the value like this:
#RequestMapping(value="/personform")
Your view resolver cannot find a correct mapping without the above #requestMapping annotation.
Note that jsp page under WEB-INF directory cannot be directly accessed by typing the uri in the browser, you have to use controller or servlet (in your case it is controller) to access it.

Related

How to resolve view in thymleaf + Springboot?

Currently, i have function, which is to convert the data from MYSQL to CSV. The CSV function contain the webconfig where use the viewResolver. The problem is, when i used below function, the page cannot view but the CSV file can be download and vice versa. Is there anything that i need to configure ?
-Configure ContentNegotiatingViewResolver
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
WebConfig- full code
package com.portal.dmtt.csvDownload.config;
import com.portal.dmtt.csvDownload.viewResolver.CsvViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import java.util.ArrayList;
import java.util.List;
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true);
}
/*
* Configure ContentNegotiatingViewResolver
*/
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
/*
* Configure View resolver to provide Csv output using Super Csv library to
* generate Csv output for an object content
*/
#Bean
public ViewResolver csvViewResolver() {
return new CsvViewResolver();
}
}
Export Controller
package com.portal.dmtt.csvDownload.controller;
import com.portal.dmtt.repo.dmttDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class ExportController {
#Autowired
private dmttDAO dmttDAO;
/**
* Handle request to download an Excel document
*/
#GetMapping("/dl")
public String download(Model model) {
model.addAttribute("results", dmttDAO.getAllResultSet());
return "";
}
}
Abstract View
package com.portal.dmtt.csvDownload.view;
import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
public abstract class AbstractCsvView extends AbstractView {
private static final String CONTENT_TYPE = "text/csv";
public AbstractCsvView() {
setContentType(CONTENT_TYPE);
}
#Override
protected boolean generatesDownloadContent() {
return true;
}
#Override
protected final void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType(getContentType());
buildCsvDocument(model, request, response);
}
protected abstract void buildCsvDocument(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
CSV View
package com.portal.dmtt.csvDownload.view;
import com.portal.dmtt.model.exceptionMonitoring.FN_Result_Set;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
public class CsvView extends AbstractCsvView {
#Override
protected void buildCsvDocument(Map<String, Object> model, HttpServletRequest request, HttpServletResponse
response) throws Exception {
response.setHeader("Content-Disposition", "attachment; filename=\"my-csv-file.csv\"");
List<FN_Result_Set> fnResultSetList = (List<FN_Result_Set>) model.get("results");
String[] header = {"SP_ID", "SP_ID", "XFER_XMIT_STATUS", "XFER_FILE_NAME", "UPDATE_TS", "YYMM", "REMARKS"};
try {
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
csvWriter.writeHeader(header);
for (FN_Result_Set user : fnResultSetList) {
csvWriter.write(user, header);
}
csvWriter.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
View Resolver
package com.portal.dmtt.csvDownload.viewResolver;
import com.portal.dmtt.csvDownload.view.CsvView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import java.util.Locale;
public class CsvViewResolver implements ViewResolver {
#Override
public View resolveViewName(String s, Locale locale) throws Exception {
return new CsvView();
}
}
One of the problems is that your CSVViewResolver is resolving a view for any view name. You may want to return null from CSVViewResolver.resolveViewName() if s, the view name, is not empty .
Another issue is that the browser (at least my Chrome) doesn't send text/csv as Accept header, but text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Set the media type explicitly in configureContentNegotiation for CSV:
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true)
.mediaType("csv", MediaType.parseMediaType("text/csv"));
}
Remove the Bean contentNegotiatingViewResolver
You shouldn't create a contentNegotiatingViewResolver as one is provided by Spring Boot. If you provide one, you will have two of this type, and yours will not have the Thymeleaf ViewResolver. As your CSVViewResolver will return a view for any view name, the view will be resolved in the ContentNegotiatingViewResolver provided by you, not in the one provided by Spring.
Details:
The csvViewResolver bean will be picked up by the Spring Boot's ContentNegotiatingViewResolver along others like BeanNameViewResolver, ThymeleafViewResolver, ViewResolverComposite, InternalResourceViewResolver.
To debug this set a breakpoint on DispatcherServlet.resolveViewName:
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}

Spring MVC Java Config issues

I am trying to do an example to change the xml config to Java config for Spring MVC. But my simple example is not working. On running this project on server, I can't see any beans initializing or the dispatcher servlet name on console.
and I get 404 error on running the http://localhost:8080/Servlet3Example/
I have created a maven project and following is my code:
package com.project.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyDispatcherServlet extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
System.out.println("get root config");
//return new Class[]{RootConfig.class};
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
System.out.println("get web config");
return new Class[]{WebConfig.class};
}
#Override
protected String[] getServletMappings() {
System.out.println("in dispatcher servlet");
return new String[] {"/"};
}
}
And the WebConfig is:
package com.project.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages={"com.project.controllers"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setSuffix(".jsp");
viewResolver.setPrefix("/WEB-INF/views/");
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
And controller:
package com.project.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value="/",method=RequestMethod.GET)
public String home()
{
return "home";
}
}
Can you please change #ComponentScan to #ComponentScan(basePackages={"com.project.*"})

Dagger2 does not generate components in Test

As per the Dagger 2 documentation
I am trying to set up a test environment according to Dagger2's documentation
(Just for context, I have successfully done this in Dagger 1.)
The problem, specifically, is that while Dagger2 correctly generates DaggerRoboDaggerComponent (as used in App.java), it does not generate DaggerTestRoboDaggerComponent (as used in MainActivityTest.java). I have checked the directory structure to make sure it's not hiding in some obscure place, and done the requisite clean, rebuild, Invalidate Caches / Restart, etc.
If someone could please let me know the error of my ways, I'd appreciate it. Thanks in advance.
You can clone the project here
Or, browse thru the project files below:
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xx.robodagger"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.dagger:dagger:2.10'
annotationProcessor "com.google.dagger:dagger-compiler:2.10"
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.3.1"
}
App.java
package xx.robodagger;
import android.app.Application;
public class App extends Application {
static RoboDaggerComponent roboDaggerComponent;
static RoboDaggerComponent getComponent() {
return roboDaggerComponent;
}
#Override public void onCreate() {
super.onCreate();
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new RoboDaggerModule())
.build();
}
}
Foo.java
package xx.robodagger;
class Foo {
#Override public String toString() {
return "foo";
}
}
MainActivity.java
package xx.robodagger;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity {
#Inject Foo foo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
App.getComponent().inject(this);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.textview);
tv.setText(foo.toString());
}
}
RoboDaggerComponent.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Component;
#Singleton
#Component(modules={RoboDaggerModule.class})
interface RoboDaggerComponent {
void inject(MainActivity mainActivity);
}
RoboDaggerModule.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
#SuppressWarnings("unused")
#Module
class RoboDaggerModule {
#Provides
#Singleton
Foo providesFoo() { return new Foo(); }
}
And now in the test directory,
FakeFoo.java
package xx.robodagger;
class FakeFoo extends Foo {
#Override public String toString() {
return "bar";
}
}
MainActivityTest.java
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import javax.inject.Inject;
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class)
public class MainActivityTest {
TestRoboDaggerComponent testRoboDaggerComponent;
#Inject Foo foo;
#Before
public void setup() {
testRoboDaggerComponent = DaggerTestRoboDaggerComponent.builder()
.testRoboDaggerModule(new TestRoboDaggerModule())
.build();
testRoboDaggerComponent.inject(this);
}
#Test
public void fooBarTest() {
assert(foo.toString().equals("bar"));
}
}
TestRoboDaggerComponent.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Component;
#Singleton
#Component(modules={TestRoboDaggerModule.class})
interface TestRoboDaggerComponent {
void inject(MainActivityTest mainActivityTest);
}
TestRoboDaggerModule.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
#SuppressWarnings("unused")
#Module
class TestRoboDaggerModule {
#Provides
#Singleton
Foo providesFoo() { return new FakeFoo(); }
}
Delete TestRoboDaggerComponent.java, it's not needed
Modify App.java to setup the component via a protected method
#Override public void onCreate() {
super.onCreate();
setupComponent();
}
protected void setupComponent() {
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new RoboDaggerModule())
.build();
}
Modify TestApp.java to extend App, and override the previously mentioned method with the TestModule
public class TestApp extends App {
#Override
protected void setupComponent() {
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new TestRoboDaggerModule())
.build();
}
}
And finally, in the actual test, leverage Robolectric's power to specify the Application module
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class,
application = TestApp.class)
public class MainActivityTest {
private MainActivity mainActivity;
#Before
public void setup() {
mainActivity = Robolectric.setupActivity(MainActivity.class);
}
#Test
public void fooBarTest() {
TextView tv = (TextView)mainActivity.findViewById(R.id.textview);
assert(tv.getText().equals("bar"));
}
}
Notice that there isn't any DI in the actual test proper. The injection of MainActivity takes place as expected, and with the overridden module. If you have a dependency that uses #Injects in the constructor, the solution per Dagger's documentation is not to use injection in the test, but to just call the normal constructor with mocked objects. This all makes sense. I still think the originally reported issue is a bug, but whatever.

Configuring Multiple View Resolvers (Thymeleaf and Json) Spring

I am trying to configure a Spring based app, where I want to configure two view resolvers. From my controller, if I return just the string name like "login", then it should be handled by the Thymeleaf resolver, whereas if the controller's method returns an object, then appropriate json view should be used. When I try to run my application as configured below, I get the following error
"Could not resolve view with name 'login' in servlet with name
'dispatcher'"
Requesting you guys to look at the Java classes below. The first is the configuration class, the second is the Controller I am trying to use.
package com.gojha.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public ViewResolver viewResolver(ContentNegotiationManager cnm) {
ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
cnvr.setContentNegotiationManager(cnm);
return cnvr;
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
#Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine((SpringTemplateEngine) templateEngine());
return viewResolver;
}
}
Controller
package com.gojha.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
#Controller
#RequestMapping("/")
public class LoginController {
private RestTemplate restTemplate;
private class Test {
private String a;
public Test() {
super();
}
public Test(String a) {
super();
this.a = a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
#Autowired
public LoginController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
#RequestMapping(method=GET)
public String testing(){
return "login";
}
#RequestMapping(method=GET, produces="application/json")
public Test testing2(){
return new Test("wow");
}
}
I hope the code is self-explanatory.
I got it working by changing the configuration file and allocating orders to view resolvers. From what I understand, it looks like first it tries to resolve the view using ContentNegotiation, and if it fails, falls back to Thymeleaf resolver. I am marking this as the answer, if someone has a better approach, or a suggested correction, let me know.
package com.gojha.web;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
#Bean
public ViewResolver viewResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setOrder(2);
return viewResolver;
}
#Bean
public ViewResolver cnViewResolver(ContentNegotiationManager cnm) {
ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
cnvr.setContentNegotiationManager(cnm);
cnvr.setOrder(1);
List<View> views = new ArrayList<View>();
views.add(jsonView());
cnvr.setDefaultViews(views);
return cnvr;
}
#Bean
public View jsonView() {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
return view;
}
}

How configure spring multiple profiles databases javaconfig

How to start a project with spring MVC with profiles, multiple connections to the database .. and run tests with gradle?
Some time ago I'm trying to make these settings and I'm not getting what I'm doing wrong?
(Sorry for my english I'm using google translate.)
Here are my settings
Dev Settings
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/nextinfoerp
db.username=myuser
db.password=mypass
#Hibernate Configuration:
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.format_sql =true
entitymanager.packages.to.scan=br.com.nextinfo.erp
Test Settings
#Test properties:
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/nextinfoerptestdb
db.username=myuser
db.password=mypass
#Hibernate Configuration:
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.format_sql =true
entitymanager.packages.to.scan=br.com.nextinfo.erp
Gradle Settings
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
apply plugin: 'jetty'
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext.springVersion= '4.1.7.RELEASE'
ext.jacksondataTypeHibernate4 ='2.5.3'
ext.easycriteriaVersion ='3.0.0'
ext.hibernateCoreVersion ='4.3.10.Final'
ext.hibernateValidadeVersion ='5.1.3.Final'
ext.springDataVersion ='1.8.0.RELEASE'
ext.mysqlConnectionVersion= '5.1.6'
ext.servletApiVersion ='2.5'
dependencies {
testCompile 'junit:junit:4.12'
compile project(':utils')
compile"javax.servlet:jstl:1.2"
compile "org.thymeleaf:thymeleaf-spring4:2.1.2.RELEASE"
compile group: 'javax.servlet', name: 'servlet-api', version: servletApiVersion
compile group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '1.2.9'
compile group: 'org.springframework.security', name: 'spring-security-web', version: '4.0.2.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-core', version: '4.0.2.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-config', version: '4.0.2.RELEASE'
compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4:2.1.2.RELEASE'
compile group: 'org.springframework', name: 'spring-context', version: springVersion
compile group: 'org.springframework', name: 'spring-web', version: springVersion
compile group: 'org.springframework', name: 'spring-test', version: springVersion
compile group: 'org.springframework', name: 'spring-webmvc', version: springVersion
compile group: 'org.springframework.data', name: 'spring-data-jpa', version:springDataVersion
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate4', version: jacksondataTypeHibernate4
compile "org.postgresql:postgresql:9.3-1100-jdbc4"
compile group: 'uaihebert.com', name: 'EasyCriteria', version: easycriteriaVersion
compile group: 'org.hibernate', name: 'hibernate-validator', version: hibernateValidadeVersion
compile group: 'org.hibernate', name: 'hibernate-core', version: hibernateCoreVersion
compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: hibernateCoreVersion
}
class for database configuration
package br.com.nextinfo.erp.web.config;
import java.util.Properties;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#Profile("dev")
#EnableJpaRepositories("br.com.nextinfo.erp.web.dao")
#PropertySource("classpath:dev.properties")
public class DevProfileDatabase extends AbstractDatabaseConfig implements PerfilDataBase {
private static final Logger log = LoggerFactory.getLogger(DevProfileDatabase.class);
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
log.warn("settings data Source "+this.getClass().getCanonicalName());
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
protected Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
return properties;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
txManager.getEntityManagerFactory().getMetamodel().getEntities();
return txManager;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
log.warn("settings data entity manager "+this.getClass().getCanonicalName());
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
}
My class incializer
import javax.servlet.Filter;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
#Order(1)
public class Inicializer extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {ThymeleafConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {ThymeleafConfig.class,ProdProfileDatabase.class,DevProfileDatabase.class,TestProfileDatabase.class};
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
return new Filter[] { };
}
#Override
protected WebApplicationContext createRootApplicationContext() {
WebApplicationContext context =
(WebApplicationContext)super.createRootApplicationContext();
((ConfigurableEnvironment)context.getEnvironment()).setActiveProfiles("dev");
return context;
}
I'm using spring-data
the error
Servlet.init() for servlet dispatcher threw exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [br/com/nextinfo/erp/web/config/ProdProfileDatabase.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.transaction.PlatformTransactionManager]: Factory method 'transactionManager' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [br/com/nextinfo/erp/web/config/ProdProfileDatabase.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'entityManagerFactory' threw exception; nested exception is org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:664)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:536)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:490)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)
If I remove the annotation profiles and classes that use the annotation inicializer function normally,
How do I solve this?
I solved the problem by moving the database configuration classes to load along with the root settings
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {ThymeleafConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {ThymeleafConfig.class,ProdProfileDatabase.class,DevProfileDatabase.class,TestPr ofileDatabase.class};
}
I did this exchange
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {ProdProfileDatabase.class,DevProfileDatabase.class,TestPr ofileDatabase.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {ThymeleafConfig.class};
}

Resources