Controller registers, but gets 404 when returning data - spring

This is initializer for Spring. I'm not using any .xml files.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
#Configuration
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebAppConfig.class,
SecurityConfig.class,
DatabaseConfig.class,
DataSourceGenerator.class,
QuartzConfig.class,
QueueConfig.class
};
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addFilter(
"facilityFilter", new FacilityServletFilter()
).addMappingForUrlPatterns(null, false, "/api/*");
servletContext.addFilter(
"hmacFilter", new HmacFilter()
).addMappingForUrlPatterns(null, false, "/api/*");
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
}
This is one of my controllers.
#Controller
#RequestMapping(value = "/install")
public class HelloController {
#RequestMapping(value = "/hi", method = RequestMethod.GET,
consumes = "*/*", produces = "text/html")
public String sayHello(){
return "<html> <head> <title>API</title>" +
"</head> <body> <h1>Welcome to the Eric</h1>" +
"</body> </html>";
}
}
All my other controllers appear to work properly, but this one returns a 404 error when I try to hit the endpoint. The code is hit in the debugger when I invoke it via Postman.

Add #ResponseBody to your controller method, else spring would try to search for an view with the name "<html> <head> <title>API</title>..."
#Controller
#RequestMapping(value = "/install")
public class HelloController {
#RequestMapping(value = "/hi", method = RequestMethod.GET, consumes = "*/*", produces = "text/html")
#ResponseBody
public String sayHello(){
return "<html> <head> <title>API</title>" +
"</head> <body> <h1>Welcome to the Eric</h1>" +
"</body> </html>";
}
}

As suggested by Raplh you can do that but if you plan to have more of these methods might as well just replace #Controller with #RestController

Related

When using MockMvc to test the controller, a parameter passing error occurred

I am using MockMvc to test the controller. Regarding parameter import, I encountered a type mismatch problem. I tried all the json styles.But nothing works
This is my controller class::
package app.dnatask.controller;
import ......;
#Slf4j
#RestController
#RequestMapping(value = "/API/scanresultconfigure")
public class ScanResultConfigureController extends BaseController {
#RequestMapping(value = "/queryScanResultList/{taskId}/{externalname}", method = RequestMethod.POST)
public IBaseResult queryscanResultList(final HttpServletRequest request, #PathVariable final String taskId, #PathVariable final String externalname, #RequestBody Map map) throws Exception {
return runController(new IControllRunner() {
public void run(IOutResult or, CheckResult cr) throws Exception {
......
}
}
}
}
This is my test class::
package app.dnatask.controller;
import ......
#WebAppConfiguration
#ContextConfiguration(classes = {ScanResultConfigureController.class})
#ComponentScan(
includeFilters = {
#ComponentScan.Filter(type = FilterType.CUSTOM,
value = {ScanResultConfigureController.class})
},
useDefaultFilters = false,
lazyInit = true
)
public class ScanResultConfigureControllerTest extends AbstractTestNGSpringContextTests {
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#BeforeMethod
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).dispatchOptions(true).build();
System.out.println("UT starting.............");
}
#AfterMethod
public void am() {
System.out.println("UT ending.............");
}
#Test
public void testQueryscanResultList() throws Exception {
Map<String, String> testMap = new HashMap<>();
testMap.put("key1", "value1");
testMap.put("key2", "value2");
String requestJson = JSONObject.toJSONString(testMap);
mockMvc.perform(
post("/API/scanresultconfigure/queryScanResultList/001/abc")
.contentType(MediaType.APPLICATION_JSON)
.param("map", requestJson)
)
.andExpect(status().isOk())
.andDo(print());
}
}
Error message::
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported
java.lang.AssertionError: Status expected:<200> but was:<415>
This is a project implemented by springmvc framework, I use TestNG for unit testing.
Regarding my problem, the solution is as follows::
MvcResult mvcResult = mockMvc.perform(
post("/API/scanresultconfigure/queryScanResultList/{taskId}/{externalname}", "123", "abc")
.contentType(MediaType.APPLICATION_JSON)
.content(requestJson)
)
.andExpect(status().isOk())
.andDo(print())
.andReturn();

Controller are not working in Spring

I unable to understand why my controller are not redirecting to my html. Anyone can help me please?
WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.udemy.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
}
HelloWorldController.java
#Controller
#RequestMapping("/example")
public class HelloWorldController {
public static final String EXAMPLE_VIEW = "example.html";
#GetMapping("/")
public String fileUploadForm(Model model) {
return "fileDownloadView";
}
#GetMapping("/helloworld")
public String helloWorld(){
return "helloworld";
}
// #RequestMapping(value="/exampleString", method=RequestMethod.GET)
#GetMapping("/exampleString")
public String exampleString(Model model){
model.addAttribute("name","John");
return EXAMPLE_VIEW;
}
// #RequestMapping(value="/exampleMAV", method=RequestMethod.GET)
#GetMapping("/exampleMAV")
public ModelAndView exampleMAV() {
ModelAndView mav= new ModelAndView(EXAMPLE_VIEW);
mav.addObject("name", "Mike");
return mav;
}
AppInitializer
public class MyWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My project structure is well done. So my html and jsps, are inside of the root WEB-INF/views. Also, the anotation #ComponentScan, are detecting the controller. So, its not a problem of root. Anyone can tell me, why im am not redirecting to the .html , please..
Error says:
ADVERTENCIA: No mapping found for HTTP request with URI [/spring-mvc-download-example/WEB-INF/views/example.html] in DispatcherServlet with name 'dispatcher'
In your controller class, above the
#RequestMapping("/example")
Insert:
#Controller
Gonna be:
#Controller
#RequestMapping("/example")
you have to annotate class HelloWorldController with #Controller or #RestController, only then it will be picked by #Componentscan annotation.

unable to inject bean in simple spring mvc application

I am trying a simple application in the spring mvc using annotations only. In my service class, I am unable to inject DAO class even though I have used relevant annotations.Please let me know what mistake I am doing. Below are my class definitions.
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringRootConfig.class };
//return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfiguration.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.emp.controller")
public class SpringWebConfiguration extends WebMvcConfigurerAdapter{
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.emp.svc,com.emp.dao")
public class SpringRootConfig {
}
package com.emp.svc;
import org.springframework.beans.factory.annotation.Autowired;
import com.emp.dao.LoginDAO;
public class LoginSvc {
#Autowired
private LoginDAO dao;
public boolean validateLogin(){
System.out.println("In the svc method");
return dao.validateLogin();
}
}
package com.emp.dao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
#Repository
public class LoginDAO {
public boolean validateLogin(){
System.out.println("In the DAO method");
return true;
}
}
package com.emp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.emp.forms.LoginForm;
import com.emp.svc.LoginSvc;
#Controller
public class LoginController {
#RequestMapping(value = {"/login"},method = RequestMethod.GET)
public ModelAndView launchLoginPage(){
ModelAndView model = new ModelAndView();
model.setViewName("login");
return model;
}
#RequestMapping(value = {"/welcome"},method = RequestMethod.GET)
public ModelAndView validateLogin(#ModelAttribute LoginForm form){
ModelAndView model = new ModelAndView();
LoginSvc svc = new LoginSvc();
if(svc.validateLogin()){
model.setViewName("welcome");
}
else
{
model.setViewName("login");
}
return model;
}
LoginSvc is called from controller. I am expecting that in LoginSvc, LoginDAO will be injected and hence the call to dao dao.validateLogin() will be successful. But what I am getting is Null pointer at dao.validateLogin(), indicating LoginDAO is not injected.
If you can let me know what I am missing, it will be great help.
Add #Service annotation in your LoginSvc class.
package com.emp.svc;
import org.springframework.beans.factory.annotation.Autowired;
import com.emp.dao.LoginDAO;
#Service
public class LoginSvc {
#Autowired
private LoginDAO dao;
public boolean validateLogin(){
System.out.println("In the svc method");
return dao.validateLogin();
}
}
And autowire LoginSvc inside your controller. As you are creating the object yourself invoking constructor of LoginSvc, spring will not provide you autowire candidate.
#Controller
public class LoginController {
#Autowired
private LoginSvc svc;
#RequestMapping(value = {"/login"},method = RequestMethod.GET)
public ModelAndView launchLoginPage(){
ModelAndView model = new ModelAndView();
model.setViewName("login");
return model;
}
#RequestMapping(value = {"/welcome"},method = RequestMethod.GET)
public ModelAndView validateLogin(#ModelAttribute LoginForm form){
ModelAndView model = new ModelAndView();
if(svc.validateLogin()) {
model.setViewName("welcome");
} else {
model.setViewName("login");
}
return model;
}
}

vaadin + spring boot: Cannot forward to error page for request

By single view application vaadin 7.7.7, spring-boot 1.5 i check uri fragment https:/tld/#!category-name-1 from user and if the category exist show items and if not
VaadinService.getCurrentResponse().sendError(404, "page not found!");
but i got error after update spring-boot 1.5 and vaadin 7.7.7 (with embeded tomcat):
Cannot forward to error page for request [/vaadinServlet/UIDL/] 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
How can i send http error pages from vaadin to user?
ErrorPageCutomizer.java
#Component
public class ErrorPageCutomizer implements EmbeddedServletContainerCustomizer {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));
container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
}
}
RestController.java
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ErrorHandlingController implements ErrorController {
private static final String PATH = "/error";
#RequestMapping(value = PATH + "/404")
public String error404() {
return "<div style='font-weight:bold; margin-top:200px; text-align:center; font-size:160%;'>Page not found...<br>to home</div>";
}
#RequestMapping(value = PATH + "/500")
public String error500() {
return "<div style='font-weight:bold; margin-top:200px; text-align:center; font-size:160%;'>500 Internal server error...</div>";
}
#Override
public String getErrorPath() {
return PATH;
}
}
Soliution was:
#Configuration
public class AppInitializer implements WebApplicationInitializer {
#Bean
public ErrorPageFilter errorPageFilter() {
return new ErrorPageFilter();
}
#Bean
public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter) {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(filter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
}
Have you tried the SystemMessagesProvider. In that provider you could define an errorUrl for a variety of errors:
public class YourServlet extends VaadinServlet
{
#Override
protected void servletInitialized() throws ServletException
{
super.servletInitialized();
getService().setSystemMessagesProvider(new SystemMessagesProvider()
{
#Override
public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo)
{
final CustomizedSystemMessages c = new CustomizedSystemMessages();
final String errorUrl = "<url to errorpage>";
c.setSessionExpiredURL(errorUrl);
c.setSessionExpiredNotificationEnabled(false);
c.setAuthenticationErrorURL(errorUrl);
c.setAuthenticationErrorNotificationEnabled(false);
c.setCommunicationErrorURL(errorUrl);
c.setCommunicationErrorNotificationEnabled(false);
c.setCookiesDisabledURL(errorUrl);
c.setCookiesDisabledNotificationEnabled(false);
c.setInternalErrorURL(errorUrl);
c.setInternalErrorNotificationEnabled(false);
c.setSessionExpiredURL(errorUrl);
c.setSessionExpiredNotificationEnabled(false);
return c;
}
});
}

Spring static resource mapping does not work

i am trying to create a Spring MVC application with security included. All configuration is made in code, no XML-s. First, i have my WebApplicationInitializer, mapping all requests to my dispatchservlet:
public class DBCAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(DBCConfiguration.class);
ctx.setServletContext(servletContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
servlet.setMultipartConfig(new MultipartConfigElement("", 1024*1024*5, 1024*1024*5*5, 1024*1024));
}
Also there is a config file:
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = "our.dbc")
public class DBCConfiguration extends WebMvcConfigurerAdapter {
private static final Logger log = Logger.getLogger(DBCConfiguration.class);
#Bean
public InternalResourceViewResolver getInternalResourceViewResolverJsp(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
viewResolver.setOrder(0);
log.info("#### Internal view resolver 0 called...");
return viewResolver;
}
#Bean
public StandardServletMultipartResolver multipartResolver(){
log.info("#### Multipart resolver called...");
return new StandardServletMultipartResolver();
}
// #Override
// public void addResourceHandlers(final ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/resources/**")
// .addResourceLocations("/resources/");
//
// }
//
// #Override
// public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// configurer.enable();
// }
}
As you can see, i have tried both addResourceHandler and configureDefaultServletHandling, but none of those worked. Problem is that all request by default, with lowest priority end up returing welcome page (so if bad address requested, welcome is returned :), so that instead of getting the css client gets back to welcome page:
#Controller
public class FileUploadController {
private static final Logger LOG = Logger.getLogger(FileUploadController.class);
private static final String FORM = "form";
private static final String WELCOME = "welcome";
private static final String DENIED = "accessDenied";
private static final String UPLOADED_REDIRECT = "redirect:/uploaded";
#Autowired
FileUploadService uploadService;
#RequestMapping(value = "/**", method = RequestMethod.GET)
public String getWelcome() {
return WELCOME;
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage() {
LOG.info("#### /login called..." );
return "login";
}
#RequestMapping(value = { "/uploaded" }, method = RequestMethod.GET)
public String getUploaded() {
LOG.info("#### /uploaded called..." );
return "uploaded";
}
.
.
.
As i said, i also have security configured, but with default container servlet serving static resources, it whould not have to be changed. Anyway, i tried also to add permitall to resources, but no success. Anyway if i disable security it does not work either, so security is not the problem.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/welcome").permitAll()
.antMatchers("/form").access("hasRole('ADMIN')and hasRole('USER')")
.
.
.
But no chances. If i type http://localhost:8080/SpringMVC/resources/app.css instead of getting the stylesheet, browser gets back to welcome page.
Any suggestions? Any help whould be appreciated :)

Resources