I am working on a web application using SpringBoot.
The problem I am facing is as follows. The application is running fine from Eclipse, but when I deploy the project as a war in tomcat 7, it's giving me "HTTP Status 404". No exception found in tomcat logs.
Below is my controller:
#RestController
public class TinyUrlController{
#Autowired TinyUrlService tinyUrlService;
#RequestMapping("/create")
public String createUrl(#RequestParam("url") String url,HttpServletRequest request){
TinyUrl tinyUrl = tinyUrlService.createUrl(url);
return tinyUrl.toString();
}
}
Seems your application have no entry point that's why you got nothing. Just create entry point into your application.
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<Application> applicationClass = Application.class;
}
See also Spring Boot deploying guide
I suggest that you try to build your application layout by using
http://start.spring.io/
It will make a SpringBoot application
It will make java packages right too
Just remember to place your controllers under java package "demo".. otherwise they cannot be "auto wired" without more configuration...
I suggest you make a simple controller that just returns "hello" as a starter...
Related
I'm trying to run my web application based on javax.mvc, but I get 404 error. I think there should be an issue related to the application path, but I don't know exactly what's wrong.
XAMPP is installed and IntelliJ idea is configured to run tomcat7 as the web server.
Application code:
#ApplicationPath("web")
public class StoreApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<>();
set.add(ProductController.class);
return set;
}
}
Controller:
#Controller
#Path("products")
public class ProductController {
#Inject
private Models models;
#GET
public String list() {
models.put("products", Product.list());
System.out.println("helllo");
return "/WEB-INF/jsp/list.jsp";
}
}
This is a maven project. The build process is done with IntelliJ idea default settings.
Base url is set in StoreApplication.java as web with application path.
The war url is http://localhost:8080/elearning_war/ as depicted in the picture.
And the controller path is products. So I expect to show a list of products in http://localhost:8080/elearning_war/web/products, but instead, I get a 404 error page.
In my opinion, because of #ApplicationPath("web") the URL should be http://localhost:8080/web/products.
I was trying to make a spring boot jsp application. So, I had gone to http://start.spring.io/ and selected web module and application is download into local folder.
After importing project into eclipse, I made an entry into application.properties as
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Then I created one controller as
#Controller
public class HelloController {
#RequestMapping("/hello")
public String hellopage() {
return "ankit";
}
}
Lastly, I added one jsp under WEB-INF/jsp folder as ankit.jsp
After starting the application, I hit the url http://localhost:8080/hello and I get response as Whitelabel Error Page
While I spend many hours to return jsp from spring-boot mvc with no success,
I tried to return the response from controller as REST SERVICE. So, I had made only few changes
1) Replace #Controller with #RestController
2) remove entry from appliation.properties
Then, I run main class and got the successful response on hitting the url http://localhost:8080/hello
So, my question is why there is so much pain in configuring spring boot to return response into jsp page.
EDIT:
Initially, my application is started with following class:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
But after few people suggestions, i changed it to following
#SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer{
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
However, result is same. After referring to this link, I had rename WEB-INF folder to view. On hitting the /hello url, my jsp is download into my local machine.
So, rendering the jsp from controller is again a mystery.
I need to either:
made a rest application instead of web application
switch to thymeleaf template engine instead of jsp
put more research into it jsp rendering
Thanks for your answers
Things you should check when using Spring boot with JSP :
Make sure you have a subclass of SpringBootServletInitializer in you project. It should look like this :
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
Make sure to use a "war" packaging
Make sure to declare the following provided dependency in your pom.xml : spring-boot-starter-tomcat
If it still doesn't work, try it with an external server instead of the embedded tomcat.
That said, Thymeleaf or Freemarker templates will be a lot easier to deal with. Thymeleaf is used by the Spring documentation so you might want to check that.
According to your description, your application.properties is ok with
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Your Controller class is ok with
#Controller
public class HelloController {
#RequestMapping("/hello")
public String hellopage() {
return "ankit";
}
}
Your main application is ok with
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Make sure that you have created folder webapp inside main. WEB-INF inside webapp. and jsp folder inside WEB-INF. And ankit.jsp inside jsp folder.
One more thing add these dependency in your pom.xml
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
I have spring boot single page web application using angular js, bootstrap for the front end and rest API for the back-end and both front-end and back-end runs on embedded tomcat container of spring boot. I am using spring boot 1.2.7 version
Following code sample shows how I am bootstrap this spring boot application
#Configuration
#SpringBootApplication
#EnableAsync
#EnableScheduling
#ComponentScan(basePackages = { "sg.abc.test.api.config", Constant.BASE_PACKAGE, sg.abc.c4s.util.Constant.BASE_PACKAGE })
#EnableAutoConfiguration(exclude = { JndiConnectionFactoryAutoConfiguration.class, DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class })
#PropertySources({
#PropertySource(value = "classpath:jdbc.properties")
})
public class TestApp extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(TestApp.class);
#Autowired
InternalSettingService internalSettingService;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
application.headless(true);
return application.sources(TestApp.class);
}
#Bean
public ModelMapper mapper() {
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
return mapper;
}
public static void main(String[] args) {
try {
SpringApplicationBuilder builder = new SpringApplicationBuilder(EmenuApp.class);
builder.headless(false);
context = builder.run(new String[] {});
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null, "Butterfly eMenu Application already running.");
}
}
This system works without ssl configuration. However when I configure spring boot to have ssl, I am only able to access the rest api, but the web app is not getting loaded into the browser.
Could anybody advice me what could be the reason behind this wired behavior. If u require further explanations please put a comment below, I will provide more details.
It is not self signed certificate.
I got the certificate from godaddy
This is how I configured it
server.ssl.key-store=data/test.keystore
server.ssl.key-store-password=test123
server.ssl.key-password=test123
with this configuration, rest api works fine and responds to https api calls, only the web application is not responding , this is what I see in the browser
i am new to springboot application development and i generated my project with the help of this url https://start.spring.io/ and when i open this project in my IDE i had 2 classes generated
this is the first class
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TravellingApplication.class);
}}
and this is the second class
#SpringBootApplication
public class TravellingApplication {
public static void main(String[] args) {
SpringApplication.run(TravellingApplication.class, args);
}}
i really don't get it whats happening inside the configure method in my Servletinitializer class.
i can write better code configuration if i delete both of the classes
and do something like this,
class simmilar to dispatcherservlet.xml
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.travelliing")
public class WebConfig extends WebMvcConfigurerAdapter {
}
class simmilar to web.xml
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException { }
}
correct me if i am wrong. i think both ServletInitializer class and webAppInitializer is capable of same functionalities since the somehow implement WebApplicationInitializer.
except for the configure method in servletInitializer class.
whats happening with the travellingApplication class annotated with #SpringBootApplication is it simmilar to my webConfig Class which extends WebMvcConfigureAdapter
Both classes load the Spring application context.
The class with the main method (TravellingApplication) will be used if you run your application as normal java application. For example if you do Run As -> Java applciatnion from Eclipse or if you package the application as a jar and run java -jar myApp.jar from the command line.
SpringBootServletInitializer will be used to load the application context if you package the application as a war file and deploy it in Tomcat or another web server that supports Servlet 3.0+. It basically replaces the web.xml.
i really don't get it whats happening inside the configure method in
my Servletinitializer class.
TravellingApplication is a #Configuration class - it declares Spring beans and other Spring configuration, so this line - return application.sources(TravellingApplication.class); just loads this configuration (application context). The same thing that happens in the main method.
whats happening with the travellingApplication class annotated with
#SpringBootApplication is it simmilar to my webConfig Class which
extends WebMvcConfigureAdapter
#SpringBootApplication is just a shortcut to
#Configuration
#EnableAutoConfiguration
#ComponentScan
See here.
In my wicket spring based applications, I have this method to inject the spring manager to the WebApplication class:
private void initManager() {
ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
this.manager = (MyManager) applicationContext.getBean("manager");
}
I usually setup the internal error page inside the init method of my WebApplication class. Sometimes I also mount some bookmarkable pages:
public class MyApplication extends WebApplication {
#Override
protected void init() {
IApplicationSettings applicationSettings = getApplicationSettings();
applicationSettings.setInternalErrorPage(ErrorPage.class);
mountBookmarkablePage("privacy", PrivacyPage.class);
}
//............
}
My WebPage classes usually depend on my manager class, for instance:
public class ErrorPage extends WebPage {
public ErrorPage() {
MyApplication application = (MyApplication) getApplication();
add(new EmailLink(application.getManager().getMailSupport()));
}
}
So, my WebApplication class refers to one or more pages, and my pages refer to the WebApplication class. Is this a circular dependency? If yes, how can I avoid it?
I would say it is not a circular dependency but it is a configuration.
However, I think you can always inject your manager bean to the web page class as well with autowiring.
EDIT:
You may also need to enable spring annotations in applicationContext.xml as well and add some new dependencies if not already in classpath
see applicationContext.xml sample at this address and your will be pretty much similar except the scan package name. Update those values accordingly.
public class ErrorPage extends WebPage {
#Autowired
private MyManager myManager;
//setter getter methods as well
}