How to configure CharacterEncodingFilter in SpringBoot? - encoding

I encountered some encoding problems in learning Spring Boot;
I want to add a CharacterEncodingFilter like Spring 3.x.
just like this:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Since Spring Boot 1.4.2 registering your own CharacterEncodingFilter will work ONLY IF you disable Spring's own instance of this bean by setting spring.http.encoding.enabled=false in the application.properties.
However, one can resolve this matter without any Filter instantiation by adding these setting to the application.properties:
# Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
spring.http.encoding.charset=UTF-8
# Enable http encoding support.
spring.http.encoding.enabled=true
# Force the encoding to the configured charset on HTTP requests and responses.
spring.http.encoding.force=true
Source: Appendix A. Common application properties

Example code for your Application.java class, as proposed in the comments above:
#Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setForceEncoding(true);
characterEncodingFilter.setEncoding("UTF-8");
registrationBean.setFilter(characterEncodingFilter);
return registrationBean;
}

I also prefer application.properties configuration. But spring.http.encoding is depracted in the new spring boot versions (>2.3). So new application.setting should look like this:
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

I think there is no need to explicity write the following properties in application.properties file:
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
Instead if you go to pom.xml in your application and if you have the following, then spring will do the needful.

Related

Spring MVC REST nohandler error

Im new to spring MVC and REST.. I'm having an issue with a simple test controller I've put together from example I've found here and from the spring docs..
When I hit the url http://localhost:8080/test-api/user/14 I get the error below
Im getting the error:
Sep 23, 2015 11:26:55 AM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/test-api/user/14] in DispatcherServlet with name 'testapi'
Im using xml to config.. Im not ready to move to java config.
web.xml
Spring Web MVC Application
<servlet>
<servlet-name>springtest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springtest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/testapi-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
testapi-servlet.xml - only contains the component scan and annotation driven elements
<context:component-scan base-package="com.springtest.testapi" />
<mvc:annotation-driven />
SpringTest.java
package com.springtest.testapi.api;
#RestController
public class SpringTest {
#RequestMapping(value="/user/{id}", method = RequestMethod.GET)
public User getUser(#PathVariable int id) {
User u = new User(id,"Test","Me");
return u;
}
What handler should I be defining.. None of the examples or docs state that a handler needs to be defined..
Remove the contextConfigLocation.
Replace the following:
<servlet-mapping>
<servlet-name>springtest</servlet-name>
<url-pattern>/test-api</url-pattern>
</servlet-mapping>
Make sure your xml file is test-api-servlet.xml and not testapi-servlet.xml
I found my issue. I mispelled the package in the component scan. The sample code I have was edited so It didn't fully represent what I had and was actually correct.

Using Infinispan subsystem for Resteasy Cache under JBoss Wildfly-8.1.0

I have a Resteasy Web Service annotated with #Cache deployed at JBoss Wildfly-8.1.0:
#Cache
#Path("/commercialStructures")
#ApplicationScoped
public class CommercialStructureResource extends
#GET
#Path("/listGeoRegions")
#Produces(value = { APPLICATION_XML, APPLICATION_JSON })
public List<GeographicRegion> listByParentId(#QueryParam("parentId") Long parentId) {
(...)
According to Resteasy docs I need to add org.jboss.resteasy.plugins.cache.server.ServerCacheFeature to JAX-RS Application and change web.xml:
<web-app>
<context-param>
<param-name>server.request.cache.infinispan.config.file</param-name>
<param-value>infinispan.xml</param-value>
</context-param>
<context-param>
<param-name>server.request.cache.infinispan.cache.name</param-name>
<param-value>MyCache</param-value>
</context-param>
</web-app>
Questions:
How are infinispan.xml and cache name related to infinispan SubSystem configurations at standalone.xml?
Is this the correct way to Set up REST Cache under Wildfly?
Thanks!!
No change in web.xml is required, if you need basic caching follow the steps :
Cache response only for GET request when response is 200 OK,
Test environment : Jboss6.4 and maven 3.0
Dependency :
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cache-core</artifactId>
<version>Any version after 3.0</version>
</dependency>
Code Changes : Add singleton for ServerCacheFeature in your application class.
singletons.add(new ServerCacheFeature());
Add this annotation to your function :
#Cache(maxAge=15, mustRevalidate = false, noStore = false, proxyRevalidate = false, sMaxAge = 15)
noStore can be use to enable/disable to cache resp

Apache Camel + Spring (war) + Tomcat + REST

I am trying to develp a rest service using apache camel. My project is a spring mvc war deployed on tomcat.
I dont want to use apache cxf (cxf servlet).
public class SampleRouter extends RouteBuilder {
#override
public void configure() throws Exception {
from("cxfrs://http://localhost:1234/sample")
.process (new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("test");
}
})).setBody(constant("SUCCESS"));
}
}
#Path("/sample")
public class SampleResource {
#GET
public void test() {
}
}
web.xml has dispatcherservlet, contextloaderlistener.
dispatcher-servlet.xml has mvc:annotation-drivem, context:component-scan,
<camelContext id="server" trace="true" xmlns="http://camel.apache.org/schema/spring">
<contextScan />
</camelContext>
pom.xml has camel-core, camel-cxf, camel-stream, cxf-rt-transports-http-jetty, cxf-rs-frontend-jaxrs, camel-spring, spring-webmvc, spring-web, spring-context.
Tomcat runs on 8080, there seems to be no exception when server comes up. But, I tried hitting the url (http://localhost:1234/sample), nothing seems to be happening.
What am i missing? I would eventually extend this to REST to Spring DSL or REST to Java DSL with authentication, filters and interceptors.
I also tried cxf:rsServer and referred that in router class.
Also, in the future if i have to use https instead of http? or how do i have the url not hard-coded?
It may be too late, but to consume HTTP requests, one may use Apache Camel Servlet component
http://camel.apache.org/servlet.html
You need to setup the resourceClass option on the cxfrs endpoint. Here is an example
from("cxfrs://http://localhost:1234/sample?resourceClasses=my.pachage.SampleResource")
You can find some example in camel-cxfrs component page.
If you want to export a CXF service through servlet transport, you need to do some work as it said.
If you want to change the address dynamically, you can take look at the camel properties component.
If you are looking to start a camel route by a consuming cxf rest service which uses the servlet transport then you need to :
Clean up your pom.xml and remove any references to jetty.
Add the CXF servlet to your web.xml
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- all our webservices are mapped under this URI pattern -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Add the servlet-transport dependency:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf-version}</version>
</dependency>
In your spring/camel configuration
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<cxf:rsServer id="rsServer" address="/restService"
serviceClass="com.something.test.SimpleServiceImpl"
loggingFeatureEnabled="true" loggingSizeLimit="20" />
Build a route from this consumer endpoint as:
from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
.to("log:TEST?showAll=true")
You can now view/(invoke with a method) the endpoint using : http://host:port/context/services/restService?_wadl

Mixing REST and JSP in Spring MVC, Cannot find JSP

I'm sure this is a noob question, and I've spent the better part of an hour trawling stackoverflow for an answer but nobody seems to have my case so here we go...
I have a new webapp that uses Spring MVC. Most of the app (99%) is pure REST, so it doesn't have a "view" as such but rather simply sends JSON back down the wire, or sends an alternate HTTP Status for errors etc.
The exception is the login page which needs to be an actual JSP, but somehow the configuration I am using to map my REST controllers is leaving me in a state where normal JSP mappings fail.
Here's what I've got:
In my dispatcher servlet config, the relevant portions are:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
In my attempts to get it working, I have also added a mapping to the "HomeController" which currently just redirects to my login JSP:
<bean name="/" class="com.somepackage.HomeController"/>
Now, in the web.xml I have:
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-dispatcher-servlet.xml
</param-value>
</context-param>
This works fine for my RESTful controllers, which look like this:
#Controller
#RequestMapping(value = "/api/user")
public class BlahBlahController {...
My "HomeController", which just looks like this:
#Controller
#RequestMapping(value = "/")
public class HomeController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("login");
}
}
IS triggered when I hit the "/" url, but I get this error in the logs:
WARNING: No mapping found for HTTP request with URI [/WEB-INF/pages/login.jsp] in DispatcherServlet with name 'spring-dispatcher'
Now I get what it's saying, it doesn't know how to resolve /WEB-INF/pages/login.jsp (this page does exist btw), but I'm stuck as to how I need to alter things to get this to work.
I'm a little confused on how it's supposed to work. Anyone got any clues?
Thanks.
OK.. I found the answer, it's the url-pattern in the dispatcher config.
Instead of:
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
It should be
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I had actually found this answer elsewhere and tried it but "thought" it wasn't working, then realized the reason I thought this was unrelated to the root cause.
No idea why this would work and the other wouldn't.. but one problem at a time...
Put RequestMapping at the method level, I tried at my code and it worked. You don't need to define HomeController bean if you are using #Controller and having a proper "context:component-scan"
#Override
#RequestMapping(value = "/")
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("login");
}
you can also use below code if you just want to redirect a login view for all "/" access.
<mvc:view-controller path="/" view-name="login"/>
Checkout the mvc show case project from github for a helpful reference.

No Endpoint mapping found using annotation driven Spring WS 2.0.2 with dynamic wsdl

Im using annotation driven Spring WS 2.0.2 to create a simple Webservice, but the enpoint mapping was not found.
Input and Output are jdom Elements to keep it as simple as possible.
The Webservice is running with Java 1.6 on Tomcat 6.0.29 wich returns an error
page (The requested Resource () is not available) to my SoapUI Service Test.
Here is the Error I get in my logging:
WARNING: No endpoint found for [SaajSoapMessage (http://foo.bar/myTest)myRequest]
Here are the parts of the configuration I deem relvant for the Endpoint mapping:
(If there are more relevant parts I am missing please ask back...)
Schema (WEB-INF/xsd/myTest.xsd)
targetNamespace="http://foo.bar/myTest"
...
<element name="myRequest" type="tns:string"/>
<element name="myResponse" type="tns:string"/>
web.xml (WEB-INF/web.xml)
<servlet-class>
org.springframework.ws.transport.http.MessageDispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/config.xml</param-value>
</init-param>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
Spring config (/WEB-INF/spring/config.xml)
<sws:annotation-driven/>
<sws:dynamic-wsdl id="myTest"
portTypeName="myTest"
localUri="/"
targetNamespace="http://foo.bar/myTest">
<sws:xsd location="/WEB-INF/xsd/myTest.xsd"/>
</sws:dynamic-wsdl>
Endpoint (src/main/java/bar/foo/MyEndpoint.java)
#Endpoint
public class MyEndpoint{
#PayloadRoot(localPart="myRequest",namespace="http://foo.bar/myTest")
#ResponsePayload
public Element mySearch( #RequestPayload Element myRequest){
return myRequest;
}
}
Searching for a sollution I found it contained in this answer
Adding
...
xmlns:context="http://www.springframework.org/schema/context"
...
xsi:schemaLocation=" ...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd ... "
<context:component-scan base-package="bar.foo"/>
to my Spring configuration let the servlet find my Endpoint.
My problem was, that no sample code in a spring documentation I found contained
this step and its relevance.
Well - actually I found this code snipplet in a tutorial earlier, but it was a bit overloaded with features I did not need, and as in the official docs it was not explained why it was necessary.