Unable to access HTML files from spring MVC - html

I am writing basic spring mvc application which have no xml configuration its annotation based. I am trying to access html files like
" localhost:9090/help.html " but i get error
No mapping found for HTTP request with URI [/help.html] in DispatcherServlet with name 'dispatcher'
here is my config
#EnableWebMvc
#Configuration
#ComponentScan({ "com.example.test" })
public class WebConfig extends WebMvcConfigurationSupport {
#Bean
public InternalResourceViewResolver internalResourceViewResolver(){
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/jsp/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/*");
registry.addResourceHandler("/**/*").addResourceLocations("/templates/*");
}
}
my html pages are inside
webapp->templates
i have tried many question here but none helped and all of them relates to xml config
any suggestions ??

Ok I figured this out. It was just a silly mistake. In addResourceLocations i removed * at the end and bingo issued resolved
so this is wrong
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/*");
correct form is
registry.addResourceHandler("/resources/**").addResourceLocations("/resources");
Now i can access html pages directly like
localhost:8080/resources/help.html
even this is possible now
localhost:8080/help.html
because i have added another resource-handler as addResourceHandler("/*\*/**")

Related

inject model data into spring webflow in cas

I am upgrading a CAS 4 to a CAS 6. I have done several Spring Boot 2 apps, so I know what I am doing there. I can even do some webflow, but only from scratch.
The documentation clearly states not to mess with the base webflow xml, and to "inject" your own services.
How does one "inject" a service? I really just need to add a message of the day to the login page.
Does anyone have an example of something this simple?
Find below my approach, tested on a cas-maven-overlay installation with cas version at 5.3.x. Some things maybe different on cas 6 branch but I assume the main idea remains.
First, we should create an Action class that will be injected in the login flow and will add the desired message in the flow scope in order to be available at the template(view).
public class DailyMessageAction extends AbstractAction{
#Override
protected Event doExecute(RequestContext context) throws Exception {
context.getFlowScope().asMap().put("dailyMessage", "YOUR_AWESOME_MESSAGE");
return success();
}
}
Then create a WebflowConfigurer class and inject our newly created DailyMessageAction in the actions list(see doInitialize method).
public class DailyMessageWebflowConfigurer extends AbstractCasWebflowConfigurer{
final Action dailyMessageAction;
public DailyMessageWebflowConfigurer(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry flowDefinitionRegistry,
ApplicationContext applicationContext,
CasConfigurationProperties casProperties,Action dailyMessageAction){
super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
this.dailyMessageAction = dailyMessageAction;
}
#Override
protected void doInitialize() {
final Flow flow = super.getLoginFlow();
flow.getStartActionList().add(dailyMessageAction);
}
}
After that we should inject DailyMessageWebflowConfigurer in cas runtime. This is achieved by creating a configuration class and inject our configurer.
#Configuration
public class CustomWebflowConfiguration {
#Autowired
private CasConfigurationProperties casProperties;
#Autowired
#Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowDefinitionRegistry;
#Autowired
private ApplicationContext applicationContext;
#Autowired
private FlowBuilderServices flowBuilderServices;
#RefreshScope
#ConditionalOnMissingBean(name = "dailyMessageAction")
#Bean
public Action dailyMessageAction(){
return new DailyMessageAction();
}
#ConditionalOnMissingBean(name = "dailyMessageWebflowConfigurer")
#Bean
#RefreshScope
public CasWebflowConfigurer dailyMessageWebflowConfigurer(){
final DailyMessageWebflowConfigurer w = new DailyMessageWebflowConfigurer(flowBuilderServices,
loginFlowDefinitionRegistry,
applicationContext,
casProperties,
dailyMessageAction());
w.initialize();
return w;
}
}
Include our CustomWebflowConfigurationclass in META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=your_package.CustomWebflowConfiguration
The final step is to present the added message in the view. Achieved by adding this line
<div th:utext="${dailyMessage}"></div>
in the templates/casLoginView.html file.
... add a message of the day to the login page...
Modifying the spring webflow directly is not recommended in CAS. read this for more info
So if I were you instead of tinkering with spring webflow, I would try to do something like the following:
Note:
Bare in mind this might not be the recommended way to do so, but I think this will work, and much less work than overriding spring webflow
As you said you are quite familiar with Spring boot, so I won't bored you with detail implementation, I can follow up if you / other reader are confused
If your message of the day can be hard coded, just skip 1-3 and go straight with 4.
Ok here we go:
Override the CasSupportActionsConfiguration, only adding the initialFlowSetupAction bean
Adding a custom class (let named it MyInitialFlowSetupAction) and implement the InitialFlowSetupAction
In MyInitialFlowSetupAction, add something like this:
#Override
public Event doExecute(final RequestContext context) {
Event returnEvent = super.doExecute(context);
configureMyAwesomeMessageOfTheDay(context)
return returnEvent;
}
private void configureMyAwesomeMessageOfTheDay(final RequestContext context) {
String messageOfTheDay = "Spring is the best season!";//Your logic here
context.getFlowScope().put("MESSAGE_OF_THE_DAY", messageOfTheDay);
}
4 . CAS 6 is using WAR overlay, so you can overlay the html file, including this one
https://github.com/apereo/cas/blob/v6.0.3/webapp/resources/templates/casLoginView.html
overlay that file, and add your MESSAGE_OF_THE_DAY to it
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layout}">
...
<body class="login">
<main role="main" class="container mt-3 mb-3">
Message of the day is: ${MESSAGE_OF_THE_DAY}
...
</main>
</body>
</html>
See if this helps you

How to show downloaded html file in spring-boot application

I have a spring-boot application and I want to show pages which was saved in database as zip archive. It looks like on my screen. Many thanks for tips
You can use WebMvcConfigurer with overrided method addResourceHandlers(ResourceHandlerRegistry registry):
#Configuration
#EnableScheduling
public class WebConfig implements WebMvcConfigurer
where you can add folder with your data:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("**/your_folder/**").addResourceLocations("file:"+ "your_base_directory_where your_folder placed");
}
Now you can open this page used by url
http://localhost:8787/your_base_directory_where your_folder placed/maybe_another_folder/your_folder/index.html
You can add new folders in your_base_directory in runtime and load it in your application.

Error while generating json content using jersy

I'm working on jersy project when a lunch tomcat server i get this exception :
MessageBodyWriter not found for media type=application/json
This is my code :
#Path("/activities")
public class ActivityResource {
private ActivityRepository activityRepository = new ActivityRepositoryStub();
#GET
#Produces(MediaType.APPLICATION_XML)
public List<Activity> getAllActivities(){
return activityRepository.findAllActivities();
}
You need to add jersy-media-moxy jar in your Lib folder or add it in your pom.xml that why you have this error message
if you want to return xml content make shur that you have #XmlRootElement on your entity because jersy use JAXB to map java object to xml
#XmlRootElment
public class Activity {
}

Katharsis with standard spring mvc controller for posting JSON returns 400

I've integrated Katharsis with spring-boot (MVC + Security) and I'm realy happy about it.
#SpringBootApplication
#Import(KatharsisConfigV2.class)
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I began to setup security with an extra spring mvc controller to handle login and logout methods.
But with a RequestBody annotated parameters to convert json to java object, I've got a 400 response telling me required body is missing.
#RequestMapping(value = "/auth/signup", method = RequestMethod.POST)
public #ResponseBody AuthenticationResponse signup(
#RequestBody AuthenticationRequest authenticationRequest) {
...
}
When I remove the import for Katharsis configuration, everything goes fine.
#SpringBootApplication
//#Import(KatharsisConfigV2.class)
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
How could I tweak my project configuration to allow basics spring controllers to accept standard JSON?
Thanks in advance
What is the exact message in the "detail" field of the response? Katharsis-Spring provides decent error details. That should provide you a better idea of exactly what's wrong.
Remember that POST bodies in JSON API will differ from how they look in regular Spring, e.g. there needs to be a "data" field in your payload.
You may also need to configure Katharsis in your application.properties file. Katharsis can't process requests unless it's configured properly.
Hope this helps.

Can I configure Jackson JSON pretty printing from annotations or from Spring MVC controller?

I'm using Jackson 1.9.6 (codehaus) for JSON serialization of my response bodies in a Spring MVC application, and I'm having trouble finding a way to configure pretty printing. All of the code examples I've been able to find (like this and this) involve playing with an instantiation of ObjectMapper or ObjectWriter, but I don't currently use an instantiation of these for anything else. I wouldn't even know where to put this code. All of my Jackson configurations are taken care of by annotating the POJOs being serialized to JSON.
Is there a way to specify pretty printing in an annotation? I would think they would have put that in #JsonSerialize, but it doesn't look like it.
My class to be serialized looks like this:
#JsonAutoDetect
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class JSONObject implements Serializable{...}
and my Spring controller method looks like this:
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody List<Object> getMessagesAndUpdates(HttpServletRequest request, HttpServletResponse response) {
JSONObject jsonResponse = new JSONObject();
.
.
.
//this will generate a non-pretty-printed json response. I want it to be pretty-printed.
return jsonResponse;
}
I searched and searched for something similar and the closest I could find was adding this bean to my Application context configuration (NOTE: I am using Spring Boot so I am not 100% certain this will work as-is in a non-Spring Boot app):
#Bean
public Jackson2ObjectMapperBuilder jacksonBuilder()
{
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true);
return builder;
}
In my opinion, its the cleanest available solution and works pretty well.
Adding this as a separate answer so I can format the output.
As luck would have it, the non-Spring Boot solution wasn't too far from the Spring Boot solution :)
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}