I am new to Spring MVC with annonation and I am just trying a basic example for it. But I am receiving Http Stats 404 error. My files are as below :
It is a maven project. request mapping is the part of controller which is used and jsp page only list.jsp to show that msg.
errors-HTTP Status 404 - /test1/view/list.jsp
public class ADConfiguration extends WebMvcConfigurerAdapter{
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
System.out.println("hjshjshdjkah");
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/view/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
#RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView list() {
System.out.println("####################Controller part methods###");
String message = "HELLO SPRING MVC HOW R U";
return new ModelAndView("list", "message", message);
}
}
Related
I have this webapp
Here is the controller:
#Controller
#RequestMapping(value = "/update")
public class Update{
#RequestMapping(value = "/tracking_number", method = RequestMethod.POST)
public ResponseEntity<String> updateTrackingNumber(#RequestHeader(value = "order_id")String orderId,
#RequestHeader(value = "tracking_number")String trackingNumber,
HttpSession httpSession){
//url: localhost:8080/update/tracking_number
//this one works perfectly
}
#RequestMapping(value = "/order_products", method = RequestMethod.POST)
public ResponseEntity<String> updateOrderProducts(){
return ResponseEntity.ok().body("i hope to see this text");
}
}
SpringBootApplication:
#SpringBootApplication
public class MainCore extends SpringBootServletInitializer{
public static void main(String[] args){
SpringApplication.run(MainCore.class, args);
}
}
WebApplicationInitializer:
public class AppInitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext container) throws ServletException{
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.scan("com.web.foo");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container.addServlet("mvc", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
WebMvcConfigurer:
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = "com.web.foo.controller")
public class WebConfig implements WebMvcConfigurer{
#Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/jsp/");
bean.setSuffix(".jsp");
return bean;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
The structure:
com
- web
- - foo
- - - controller
- - - - Update.java
- - - MainCore.java
- - - AppInitializer.java
- - - WebConfig.java
When I access localhost:8080/update/tracking_number it works perfect.
But when I access localhost:8080/update/order_products it no longer works and gives the response:
{
"timestamp": 1618404297125,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/update/order_products"
}
Can you check if the request has Content-Type header. Also in #RequestMapping add consumes = "application/text" or "application/json" whatever is relevant.
Try add #ResponseBody methods of updateOrderProducts
The project is running directly from Intellij IDEA.
So, in my case, the solution was to Invalidate caches.
I have added multiple view resolver for PDF, Excel and InternalResourceViewResolver for JSP files. PDF and Excel resolver works fine but when I call /test that is calling my test (test.jsp) I see a blank page. But when I remove other resolvers or disable my webconfig then test.jsp (/test) loads fine.
Following is the error I see when calling /test (binded to test controller and test.jsp):
2018-08-11 23:43:06.191 ERROR 12136 --- [nio-9090-exec-1] o.s.boot.web.support.ErrorPageFilter : Cannot forward to error page for request [/test] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
Also, following is my webconfig responsible for adding multiple resolvers (pdf, excel and jsp pages):
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true);
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/*
* 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(internalResourceViewResolver());
resolvers.add(pdfViewResolver());
resolvers.add(excelViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
#Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp");
resolver.setSuffix(".jsp");
return resolver;
}
/*
* Configure View resolver to provide XLS output using Apache POI library to
* generate XLS output for an object content
*/
#Bean
public ViewResolver excelViewResolver() {
return new ExcelViewResolver();
}
/*
* Configure View resolver to provide Pdf output using iText library to
* generate pdf output for an object content
*/
#Bean
public ViewResolver pdfViewResolver() {
return new PdfViewResolver();
}
}
Im having trouble using redirect functionality within my spring boot application. As shown in my code below im returning "redirect:/aucConfirm/" but when i initiate this i get a "This application has no explicit mapping" error.
#Controller
#RequestMapping("/")
public class WelcomeController {
#Autowired
AuctionItemRepository aucRepository;
// inject via application.properties
#Value("${welcome.message:test}")
private String message = "Hello World";
#RequestMapping(value = "/")
public String welcome(Map<String, Object> model) {
model.put("message", this.message);
return "welcome";
}
#RequestMapping(value = "/sell", method = RequestMethod.GET)
public String addAuction(Model model, HttpServletRequest request) {
model.addAttribute("newAuction", new AuctionItem());
return "NewAuction";
}
#RequestMapping(value = "/sell", method = RequestMethod.POST)
public String saveAuction(#ModelAttribute AuctionItem newAuction, RedirectAttributes attributes){
return "redirect:/aucConfirm";
}
#RequestMapping(value = "/aucConfirm", method = RequestMethod.GET)
public String confirmNewAuction(Model model, HttpServletRequest request) {
return "aucConfirm";
}
}
This is my current configuration class -
#SpringBootApplication
#ComponentScan
#EnableJpaRepositories("All")
#EntityScan("All")
public class AuctionWebApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AuctionWebApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(AuctionWebApplication.class, args);
}
#Bean
DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/auctiondb?zeroDateTimeBehavior=convertToNull");
dataSource.setUsername("root");
dataSource.setPassword("toor");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setDataSource(dataSource);
entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManager.setPackagesToScan("All");
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");
jpaProperties.setProperty("hibernate.id.new_generator_mappings", "false");
entityManager.setJpaProperties(jpaProperties);
return entityManager;
}
}
Update
Could it possibly have something to do with my jsp page that im trying to establish the recommit? I have a mvc form here -
<mvc:form class="form-inline" action="${action}" method="post" modelAttribute="newAuction" id="addNewAuc">
and when the user hits the next button it should hit the "redirect:/aucConfirm" -
<button type="submit" name="submit" class="btn btn-success" form="addNewAuc">Next</button>
Is there anything wrong with this code? Im running out of ideas at this point. Do i need to add anything to my spring boot configuration class to get it working? - Please help!
Update 2
http://localhost:8080/AuctionWebsite/sell
When i enter details int this form and select next i want it to redirect to-
http://localhost:8080/AuctionWebsite/aucConfirm
However this is what appears-
not redirecting at all and remaining with link http://localhost:8080/AuctionWebsite/sell
http://localhost:8080/AuctionWebsite/aucConfirm works when entered manually
Im getting a little bit desperate at this point, would really appreciate any help.
Use this code
redirect:aucConfirm
Instead of
redirect:/aucConfirm
As per your updated question. it seems that
"This application has no explicit mapping" error
Is for /error url;
The actual error is
Validation failed for object 'auctionItem'
So problem is not with redirection , it is something else related to validation. You may find specific error on console log.
I could not get this to work (with or without a '/' after the ':')...
#PostMapping("/customer/update")
public String customerUpdate(Customer customer) {
customerRepository.save(customer);
return "redirect:customer/list";
}
...so went with this...
#PostMapping("/customer/update")
public RedirectView customerUpdate(Customer customer) {
customerRepository.save(customer);
return new RedirectView("/customer/list");
}
This question already has answers here:
Why does Spring MVC respond with a 404 and report "No mapping found for HTTP request with URI [...] in DispatcherServlet"?
(13 answers)
Closed 6 years ago.
I declared UrlBasedViewResolver method in RestAppConfig to render jsp page.
#Bean
public UrlBasedViewResolver urlBasedViewResolver(){
UrlBasedViewResolver res = new InternalResourceViewResolver(); //new UrlBasedViewResolver();//
res.setOrder(10);
res.setViewClass(JstlView.class);
res.setPrefix("/views/templates/");
res.setSuffix(".jsp");
return res;
}
and delclared ModelAndView method in controller BaseController
#Configuration
#EnableWebMvc
#ComponentScan(basePackages={"kr.co.cdefi.base.restapp.controller"}
, useDefaultFilters=false
, includeFilters={#Filter(Controller.class)
, #Filter(ControllerAdvice.class)})
public class RestAppConfig extends WebMvcConfigurerAdapter{
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.useJaf(true)
.favorPathExtension(true)
.favorParameter(false)
.ignoreAcceptHeader(false)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML);
};
#Bean
public UrlBasedViewResolver urlBasedViewResolver(){
UrlBasedViewResolver res = new InternalResourceViewResolver(); //new UrlBasedViewResolver();//
res.setOrder(10);
res.setViewClass(JstlView.class);
res.setPrefix("/views/templates/");
res.setSuffix(".jsp");
return res;
}
}
finally, I run tomcat8 server using Eclipse.
But requested URI /home just responses this.
WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/TheBigs/views/templates/index.jsp] in DispatcherServlet with name 'rest-app'
I opened deployment location
...\org.eclipse.wst.server.core\tmp1\wtpwebapps\TheBigs\views\templates\
... files exists. What is the problem? Is there anything I missing?
I added my controller code BaseController
#Controller
public class BaseController {
Logger logger = LoggerFactory.getLogger(BaseController.class);
#Autowired UserService userService;
#RequestMapping(value="/home", method = RequestMethod.GET)
public ModelAndView home(){
logger.debug("home!");
ModelAndView view = new ModelAndView();
view.setViewName("index");
return view;
}
#RequestMapping(value="/", method = RequestMethod.GET)
public String index(Model model){
logger.debug("index page!");
model.addAttribute("message", "success");
return "test";
}
}
There images are jsp files directory, and Web Deployment Assembly defined.
Solved. It caused by servlet-mapping.
I changed url-pattern set to / from /*, then works.
Every request in my java application produces 2 other requests with a HTTP 302 error.
For example, if a request is made to view a webpage called board.html, this request is made from home.html. I get 3 requests produced in the following order:
POST home.html - 302 Moved Temporarily
GET board.html - 302 Moved Temporarily
GET board.html - 200 OK
I expect to get just the final request only and cant find out why the other 2 are occurring.
This pattern occurs for all requests causing my filters to fire 3 times.
The project uses spring webflow.
After lot of reading was finally able to change the default behaviour
( default behaviour was - Get request , post (302/303 - redirect as per location appended for each request ) , finally a get call.
So for one request we will send a Get Request then Service will return 302/303 with location attribute ( ie redirected with query param ) and as a response HTML with QueryString usually e1s1 is loaded. Sample proj is in this link and following is the change that is been implemented to avoid this default behaviour as following
To avoid 303/302 which has unpredictable behaviour i have stoped redirection with following addition to Config Class
#Configuration
public class WebFlowWithMvcConfig extends AbstractFlowConfiguration {
//implements WebMvcConfigurer
#Autowired
private LocalValidatorFactoryBean localValidatorFacotryBean;
/*
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
}
*/
#Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder() //
.setBasePath("classpath:flows") //
.addFlowLocationPattern("/**/*-flow.xml") //
.setFlowBuilderServices(this.flowBuilderServices()) //
.build();
}
#Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(this.flowRegistry())
.setAlwaysRedirectOnPause(false)
.setRedirectInSameState(false)
.build();
}
#Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder() //
.setViewFactoryCreator(this.mvcViewFactoryCreator()) // Important!
.setValidator(this.localValidatorFacotryBean)
.build();
}
// ----------------------------------------------------------
#Bean
public FlowHandlerMapping flowHandlerMapping() {
FlowHandlerMapping handlerMapping = new FlowHandlerMapping();
handlerMapping.setOrder(-1);
handlerMapping.setFlowRegistry(this.flowRegistry());
//handlerMapping.setInterceptors(new LogInterceptor());
return handlerMapping;
}
#Bean
public FlowHandlerAdapter flowHandlerAdapter() {
FlowHandlerAdapter handlerAdapter = new FlowHandlerAdapter();
handlerAdapter.setFlowExecutor(this.flowExecutor());
handlerAdapter.setSaveOutputToFlashScopeOnRedirect(true);
//handlerAdapter.setStatusCode(HttpStatus.SEE_OTHER);
//handlerAdapter.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
return handlerAdapter;
}
#Bean
public ViewFactoryCreator mvcViewFactoryCreator() {
MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
factoryCreator.setViewResolvers(Collections.singletonList(this.thymeleafViewResolver()));
factoryCreator.setUseSpringBeanBinding(true);
return factoryCreator;
}
#Bean
#Description("Thymeleaf AJAX view resolver for Spring WebFlow")
public AjaxThymeleafViewResolver thymeleafViewResolver() {
AjaxThymeleafViewResolver viewResolver = new AjaxThymeleafViewResolver();
viewResolver.setViewClass(FlowAjaxThymeleafView.class);
viewResolver.setTemplateEngine(this.templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
#Bean
#Description("Thymeleaf template resolver serving HTML 5")
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
#Bean
#Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(this.templateResolver());
return templateEngine;
}
}
So we have made following as false
.setAlwaysRedirectOnPause(false)
.setRedirectInSameState(false)
Which will avoid location redirect now the similar change has to be implemented in the template html's too. So the change was to add an action url to html template wherever form is present as following
<form .. th:action="${flowExecutionUrl}">
Which successfully does form submission and responds with 200 Ok http status and html page. Hence no more (GET - 200 to 302 redirect to 200) instead direct single request call with Get 200/Post 200 and response is binded to Html page.
In this way just the final request only with response is present.
I hope this would be helpful for others.