How to link to view file in controller by click view name - spring-boot

A springboot web project,work by idea . in the controller code,I want to click "manage/operate/createCluster" ,then the idea will open the /web-inf/jsp/manage/operate/createCluster.jsp file.
How to achieve or what information can be referenced?
#RequestMapping(value = "createCluster", method = RequestMethod.GET)
public ModelAndView doClusterList(HttpServletRequest request,
HttpServletResponse response, Model model) {
model.addAttribute("activeMenuId","createCluster");
return new ModelAndView("manage/operate/createCluster");
}

If you want just affiche a view without any data to populate you can add a view controller in Your WebMvc config class like :
#Configuration
#EnableWebMvc
#ComponentScan
public class WebConfig implement WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/manage/operate/createCluster").setViewName("manage/operate/createCluster");
}
}
If you want to send data in your view as your example you must just send the view name as String:
#RequestMapping(value = "createCluster", method = RequestMethod.GET)
public String doClusterList(HttpServletRequest request,
HttpServletResponse response, Model model) {
model.addAttribute("activeMenuId","createCluster");
return "manage/operate/createCluster";
}
You should add config of your view Resolver for both cases :
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}

Related

Request Post not allowed for controller, but get works

I have a spring-boot with a cors. I want set a static page controller,
I want return a static html page for same post/get request.
The get request works, but with the post request i have :
{
"timestamp": 1563296215801,
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'POST' not supported",
"path": "/test"
}
My code :
#Controller
#RequestMapping("/")
public class StaticPageController implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName(
"test");
}
#RequestMapping(value = "test", method = { RequestMethod.GET,
RequestMethod.POST })
public String test() {
return "test";
}
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("folder/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
With the post request, my breakpoint in 'return "test";' is fired. But after i have a 405 error...
Any ideas ?
You are facing the issue because along with configuring the GET endpoint for /test , you have also configured the ViewControllerRegistry to return the view test to /test url.
The ViewControllerRegistry is configured whenever you want to serve a static content without the need of a controller. So , try removing that and your controller method should work as expected because by default only GET is supported by ViewControllerRegistry.
Assists with the registration of simple automated controllers pre-configured with status code and/or a view. ViewControllerRegistry
registers view controller.
We need not to create actual controller class when using ViewControllerRegistry. It is used when we just need to map a URL
with a view. addViewController(String urlPath): It adds a view
controller for the given URL.
This method returns ViewControllerRegistration and using ViewControllerRegistration.setViewName() a corresponding view is
mapped. addRedirectViewController(String urlPath, String
redirectUrl): It maps a URL to another URL to redirect on it. It has
been introduced in spring 4.1.
addStatusController(String urlPath, HttpStatus statusCode): It maps a URL with given status code. It has also been introduced in spring
4.1.
Try using :
#Controller
#RequestMapping("/")
public class StaticPageController implements WebMvcConfigurer {
#RequestMapping(value = "test", method = { RequestMethod.GET,
RequestMethod.POST })
public String test() {
return "test";
}
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("folder/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}

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.

Spring custom view resolver

I've tried to change the prefix of the view based on the useragent.
If the request comes from IE then trying to forward it to "legacy" folder otherwise "modern" folder.
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setSuffix(".jsp");
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if(request.getHeader("User-Agent").contains("Internet Explorer")){
internalResourceViewResolver.setPrefix("/WEB-INF/views/legacy/");
} else {
internalResourceViewResolver.setPrefix("/WEB-INF/views/modern/");
}
return internalResourceViewResolver;
}
Its not at all working. Can anyone suggest?
Don't hack around in the ViewResolver write a HandlerInterceptor instead.
public class BrowserPrefixHandlerInterceptor extends HandlerInterceptorAdapter {
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
if(request.getHeader("User-Agent").contains("Internet Explorer")){
modelAndView.setViewName("legacy/" + modelAndView.getViewName());
} else {
modelAndView.setViewName("modern/" + modelAndView.getViewName());
}
}
}
Then register is like a regular interceptor.
#Configuration
public YourWebConfiguration extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BrowserPrefixHandlerInterceptor());
}
}
Just leave the ViewResolver alone. This will work for each ViewResolver and not just for your own customized version. You might want to make the interceptor a little smarter (check if there is actually a viewName and maybe skip it for certain URLs).

The requested resource is not available when wanna map to .html file

I'm using Spring mvc, and wanna make web app which send some json data to client and client should visualized them using js.
I have some questions:
1-My project have some *.html beside *.jsp file how can I handle both without web.xml. the code that i had written work fine with *.jsp but give "The requested resource is not available." error for mapping html files.
2-As i said My service have to send a list of object in json form to client, when i want to parse the json string on server in *.jsp file with the code like
MyClass data = new Gson().fromJson(MyList.get(0).toString(), listType)
,I face with to many problems, so i decide to do this job in client Side in *.html file, i want to know how should i handle this parsing job when i don't want that client know about the structure my class? OR plz tell if have to share my class with client, how should i send stucture of it to html file?
3-How should i access to data that i created in restapi.jsp on the UserSideApp.html file?
these are some my files:
AppInitializer.java
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
} }
AppConfig.java
public class AppConfig {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix("");
return viewResolver;
} }
the part of my AppContoller.java
#Controller
#RequestMapping("/")
public class AppController {
#Autowired
HackDataService service;
#RequestMapping(value = "/restapi", method = RequestMethod.GET)
public String jsonAPI(ModelMap model) {
List<HackData> newList = service.findAllNewData();
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json="";
try {
json = ow.writeValueAsString(newList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
model.addAttribute("List", json);
String newjson = new Gson().toJson(newList);
model.addAttribute("newList", newjson);
return "newTest.jsp";
}
#RequestMapping(value = "/app", method = RequestMethod.GET)
public String htmlapp() {
return "UserSideApp.html";
} }
and my both .html and .jsp files are in "/WEB-INF/views/"
After spending almost a day on first problem, i find the answer of it,
first of all instead of implementing WebApplicationInitializer, I extend AbstractAnnotationConfigDispatcherServletInitializer and for java Configing i extends WebMvcConfigurerAdapter.
Then i create a pages folder in WEB-INF and my codes changes to these:
AppInitializer became like other internet's samples.
AppConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.attackmap" })
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/WEB-INF/pages/");
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix("");
return viewResolver;
}
}
AppController.java
#Controller
#RequestMapping("/")
public class AppController {
#RequestMapping(value = { "/", "/info" }, method = RequestMethod.GET)
public String welcome(ModelMap model) {
model.addAttribute("message", "home page with info about site");
return "homepage.jsp";
}
#RequestMapping(value = "/finalapp", method = RequestMethod.GET)
public String test() {
return "redirect:/pages/final.htm";
} }
there was another way
Creating a "resources" directory in "src/main/webapp"
add bellow cod in AppConfig.java
registry.addResourceHandler("/WEB-INF/views/resources/*.html").addResourceLocations("/resources/");
and for viewResolving use the code like bellow:
#RequestMapping(value = "/newapp", method = RequestMethod.GET)
public String test2() {
return "/resources/UserSideAppNew.html";
}
but still my two other questions are unsolved, the main problem was first one but if you know sth, about these two plz tell me about them

How can i separate jsp in differents folders with Spring?

This is my AppInitializer:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.project.app")
public class AppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer implements
WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
And this is my AppConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.acfcm.app")
#Import({ SecurityConfig.class })
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolverForClasses() {
ResourceBundleViewResolver viewResolver = new ResourceBundleViewResolver();
viewResolver.setOrder(1);
viewResolver.setBasename("views");
return viewResolver;
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setOrder(2);
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
}
What I want is how to change the AppConfig to put .jsp in differents foldes into the project because right now only can save it in /WEB-INF/views/ and there is a lot of .jsp!! I want to have two more folders to see my project like:
WEB-INF/views/moduleOne/
WEB-INF/views/moduleTwo/
...
Thanks!
I think your code is all fine; it will look for your JSPs starting in /WEB-INF/views/
Most people do like you say and break up JSP views under folders like /admin, /common, etc.
The way you do this is to specify the subfolder in the controller. For example, in your controller, you could return:
#RequestMapping(value = "/admin/index.htm", method = RequestMethod.GET)
public ModelAndView index(HttpServletRequest request,
HttpServletResponse response)
{
Map<String, Object> myModel = new HashMap<String, Object>();
myModel.put("someValues", new ArrayList());
ModelAndView mv = new ModelAndView("admin/index","model", myModel);
return mv;
}
Doing it like the above, you can put your JSP under
/WEB-INF/views/admin/index.jsp
Of course, your mappings (/admin) doesn't have to match the directory structure (/WEB-INF/views/admin) but we chose to make both match, to make it faster to find the code (if controller mapping matches the dir structure).
The important thing to remember is that whatever you put in that ModelAndView first param, Spring will prepend and append the values you defined in your code:
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
So, if you return ModelAndview("/pierre/was/here/something"), Spring will try to find the JSP at location: "/WEB-INF/views/pierre/was/here/something.jsp"
The common practice is to have the configuration as yours, and in the request handler controller methods, use the view names as moduleOne/view1, moduleTwo/view2 etc.

Resources