I am trying to trim the JSON key in order to avoid spaces in the JSON requests.
JSON Object would look like with white space, (check for "eq")
{
"page": 0,
"size": 25,
"and":{
"eq ": [
{
"field":"id",
"value": "60536"
}
]
}
}
I find lot of solution ranging from SimpleModule to JsonDeserializer but all generally work on the value part. How can I trim the key itself which then correctly converts into my Java POJO?
public class SearchInDTO implements InDTO {
private Integer pageNo;
private Integer pageSize;
private ANDFilter andFilter;
#JsonProperty("page")
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
#JsonProperty("size")
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
#JsonProperty("and")
public ANDFilter getAndFilter() {
return andFilter;
}
public void setAndFilter(ANDFilter andFilter) {
this.andFilter = andFilter;
}
public static class EQFilter extends FieldValue
{
#JsonProperty("field")
public String getFieldName() {
return super.getFieldName();
}
#JsonProperty("value")
public String getValue() {
return super.getValue();
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("EQFilter{");
sb.append(super.toString());
sb.append('}');
return sb.toString();
}
}
public static class FieldValue
{
private String fieldName;
private String value;
#JsonProperty("field")
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
#JsonProperty("value")
public String getValue() {
if(value == null) return value;
return value.toLowerCase();
}
public void setValue(String value) {
this.value = value;
}
}
public static class ANDFilter {
private List<EQFilter> eqFilters = new ArrayList<>();
#JsonProperty("eq")
public List<EQFilter> getEqFilters() {
return eqFilters;
}
public void setEqFilters(List<EQFilter> eqFilters) {
this.eqFilters = eqFilters;
}
}
}
Solution with custom JsonParser implementation:
public class MyJsonParser extends JsonParserDelegate {
public MyJsonParser(JsonParser parser) {
super(parser);
}
#Override
public String getCurrentName() throws IOException {
return super.getCurrentName().trim();
}
}
public class MyJsonParserFactory extends MappingJsonFactory {
#Override
protected JsonParser _createParser(InputStream in, IOContext ctxt) throws IOException {
return new MyJsonParser(super._createParser(in, ctxt));
}
#Override
protected JsonParser _createParser(Reader r, IOContext ctxt) throws IOException {
return new MyJsonParser(super._createParser(r, ctxt));
}
#Override
protected JsonParser _createParser(char[] data, int offset, int len, IOContext ctxt, boolean recyclable) throws IOException {
return new MyJsonParser(super._createParser(data, offset, len, ctxt, recyclable));
}
#Override
protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException {
return new MyJsonParser(super._createParser(data, offset, len, ctxt));
}
#Override
protected JsonParser _createParser(DataInput input, IOContext ctxt) throws IOException {
return new MyJsonParser(super._createParser(input, ctxt));
}
}
#Component
public class MyJackson2ObjectMapperBuilderCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
#Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.factory(new MyJsonParserFactory());
}
}
I am deleveloping web project EJB,JPA - Hibernate as provider, JBoss 6,MySql.
I new in EJB, JPA.I have problems with load ejb bean in servlet.
persistence.xml
<persistence-unit name="LibraryPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>library.entity.User</class>
<class>library.entity.Book</class>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
UserFacade.java
#Local
public interface UserFacade {
User findUserByLoginAndPassword(String login, String password);
/* List<User> getClients();
void returnBooks(long userId, long[] ids);
void takeBooks(long userId, long[] ids);*/
}
UserFacadeImpl.java
package library.facades.impl;
import library.dao.impl.UserDAO;
import library.entity.User;
import library.facades.interfaces.UserFacade;
import javax.ejb.EJB;
import javax.ejb.Stateless;
#Stateless
public class UserFacadeImpl implements UserFacade {
#EJB
private UserDAO userDAO;
public UserFacadeImpl() {
}
public User findUserByLoginAndPassword(String login, String password) {
User user = userDAO.selectUserByLoginAndPassword(login, password);
return user;
}
/* public List<User> getListClients() {
List<User> userList = userDAO.getClients();
return userList;
}
public void returnBooks(long userId, long[] ids) {
userDAO.returnBooks(userId, ids);
}
public void takeBooks(long userId, long[] ids) {
userDAO.takeBooks(userId, ids);
}*/
}
UserDAO.java
package library.dao.impl;
import library.dao.interfaces.GenericDAO;
import library.entity.User;
import javax.ejb.Local;
import javax.ejb.Stateless;
import java.util.HashMap;
import java.util.Map;
#Stateless
public class UserDAO extends GenericDAO {
public UserDAO() {
super(User.class);
}
public User selectUserByLoginAndPassword(String login, String password) {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("login", login);
parameters.put("password", password);
return (User) super.findOneResult(User.SELECT_USER_BY_LOGIN_AND_PASSWORD, parameters);
}
/*public List<User> getClients() {
Query namedQuery = entityManager.createNamedQuery(User.ALL_CLIENTS, User.class);
List<User> clientsList = namedQuery.getResultList();
return clientsList;
}
#Override
public void returnBooks(long userId, long[] ids) {
User user = entityManager.find(User.class, userId);
for (long id : ids) {
Book book = entityManager.find(Book.class, id);
user.getTakenBooks().remove(book);
}
entityManager.merge(user);
}
#Override
public void takeBooks(long userId, long[] ids) {
User user = entityManager.find(User.class, userId);
for (long id : ids) {
Book book = entityManager.find(Book.class, id);
user.getTakenBooks().add(book);
}
entityManager.merge(user);
}*/
}
GenericDAO.java
package library.dao.interfaces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
import java.util.Map;
public abstract class GenericDAO<T> {
private static final String LIBRARY_PERSISTENCE_UNIT = "LibraryPersistenceUnit";
#PersistenceContext(unitName = LIBRARY_PERSISTENCE_UNIT)
private EntityManager entityManager;
private Class<T> entityClass;
public GenericDAO() {
}
public GenericDAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
public void save(T entity) {
entityManager.persist(entity);
}
protected void delete(Object id, Class<T> classe) {
T entityToBeRemoved = entityManager.getReference(classe, id);
entityManager.remove(entityToBeRemoved);
}
public T update(T entity) {
return entityManager.merge(entity);
}
public T find(int entityID) {
return entityManager.find(entityClass, entityID);
}
// Using the unchecked because JPA does not have a
// entityManager.getCriteriaBuilder().createQuery()<T> method
#SuppressWarnings({"unchecked", "rawtypes"})
public List<T> findAll() {
/* CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));*/
return null;//entityManager.createQuery(cq).getResultList();
}
// Using the unchecked because JPA does not have a
// ery.getSingleResult()<T> method
#SuppressWarnings("unchecked")
protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
T result = null;
try {
Query query = entityManager.createNamedQuery(namedQuery);
// Method that will populate parameters if they are passed not null and empty
if (parameters != null && !parameters.isEmpty()) {
populateQueryParameters(query, parameters);
}
result = (T) query.getSingleResult();
} catch (Exception e) {
System.out.println("Error while running query: " + e.getMessage());
e.printStackTrace();
}
return result;
}
private void populateQueryParameters(Query query, Map<String, Object> parameters) {
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
LibraryController
package library.controller;
import library.entity.User;
import library.facades.interfaces.UserFacade;
import library.resourses.constants.Constants;
import library.resourses.enums.Role;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LibraryController extends HttpServlet {
#EJB
private UserFacade userFacade;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
performAction(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
performAction(request, response);
}
private void performAction(HttpServletRequest request, HttpServletResponse response) {
String pageType = request.getParameter(Constants.PAGE_TYPE);
if (pageType != null) {
try {
String page = null;
String login = request.getParameter(Constants.USER_LOGIN);
String password = request.getParameter(Constants.USER_PASSWORD);
User user = userFacade.findUserByLoginAndPassword(login, password);
if (user == null) {
request.getSession().setAttribute(Constants.ERROR,
Constants.ERROR_MESSAGE_7);
page = Constants.MAIN_PAGE;
} else {
String namePage = user.getRole().toString().toLowerCase();
if (isClient(user)) {
request.getSession().setAttribute(Constants.CLIENT,
user);
request.getSession().setAttribute(Constants.ERROR, null);
} else if (isAdministrator(user)) {
request.getSession().setAttribute(Constants.ADMINISTRATOR,
user);
request.getSession().setAttribute(Constants.ERROR, null);
}
page = Constants.START_PAGES + namePage + Constants.END_PAGES;
}
RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher(page);
requestDispatcher.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private boolean isAdministrator(User user) {
return user.getRole().equals(Role.ADMINISTRATOR);
}
private boolean isClient(User user) {
return user.getRole().equals(Role.CLIENT);
}
}
I get null for userFacade.Can you explain me what I do wrong.
Thanks.
The problem is that instead of letting the container instantiate and inject the DAO for you, you explicitely create the DAO instance by yourself:
private IUserDAO dao;
public UserService() {
dao = UserDAOImpl.getInstance();
}
For the EntityManager to be injected into the DAO, the container must instantiate it, not you. Replace the above code with the following, which uses dependency injection, and will thus also have the advantage of making your code testable:
#Inject
private IUserDAO dao;
I have an entity like this:
#Entity
#Table(name = "PLATFORM")
public class Platform{
#Id
#Column(name = "PLATFORM_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer platformId;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="PLATFORM_TYPE_ID")
private PlatformType platformType;
//must be manytomany but how?
private List<MimeType> supportedMimeTypes;
...
And I have a MimeType class which is a org.hibernate.usertype.UserType indeed.
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MimeType extends EnumarationType{
private static final long serialVersionUID = 1L;
public static final MimeType XML = new MimeType(new Integer(0), "XML");
public static final MimeType JSON = new MimeType(new Integer(1), "JSON");
protected static ArrayList<MimeType> list = new ArrayList<MimeType>();
static {
SQL_TYPES = new int[] { Types.INTEGER };
list.add(XML);
list.add(JSON);
}
public MimeType(){
}
public MimeType(Integer value, String label) {
super(value, label);
}
public List<?> getList() {
return list;
}
public static MimeType getById(int id) {
Iterator<MimeType> it = list.iterator();
while (it.hasNext()) {
MimeType status = it.next();
int statusId = Integer.parseInt(status.getValue());
if (statusId == id)
return status;
}
return null;
}
public static MimeType getByName(String name) {
Iterator<MimeType> it = list.iterator();
while (it.hasNext()) {
MimeType status = it.next();
String statusName = status.getLabel();
if (statusName.equalsIgnoreCase(name))
return status;
}
return null;
}
}
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public abstract class EnumarationTypeBase implements UserType, Serializable {
protected static int[] SQL_TYPES = { Types.VARCHAR };
protected String label;
protected Object value;
protected String resourceKey;
public EnumarationTypeBase() {
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public abstract List<?> getList();
private Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public EnumarationTypeBase resolveFromValue(Object value) {
List<?> list = getList();
if (list == null)
return null;
EnumarationTypeBase result = null;
for (Iterator<?> itr = list.iterator(); itr.hasNext();) {
EnumarationTypeBase enm = (EnumarationTypeBase) itr.next();
if (enm.getValue().toString().equals(value.toString())) {
result = enm;
break;
}
}
return result;
}
public EnumarationTypeBase resolveFromLabel(Object label) {
List<?> list = getList();
if (list == null)
return null;
EnumarationTypeBase result = null;
for (Iterator<?> itr = list.iterator(); itr.hasNext();) {
EnumarationTypeBase enm = (EnumarationTypeBase) itr.next();
if (enm.getLabel().equals(label.toString())) {
result = enm;
break;
}
}
return result;
}
public String toString() {
return getLabel();
}
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class<?> returnedClass() {
return getClass();
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException,
SQLException {
value = resultSet.getString(names[0]);
return resultSet.wasNull() ? null : resolveFromValue(value);
}
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException,
SQLException {
EnumarationTypeBase enumType = (EnumarationTypeBase) value;
if (value == null) {
statement.setNull(index, sqlTypes()[0]);
} else {
statement.setString(index, enumType.getValue().toString());
}
}
public boolean equals(Object x, Object y) {
if (x == y)
return true;
if (null == x || null == y)
return false;
return x.equals(y);
}
public boolean equals(Object obj) {
if (obj instanceof EnumarationTypeBase)
return this.getValue().equals(((EnumarationTypeBase) obj).getValue());
return super.equals(obj);
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public Object deepCopy(Object value) {
return value;
}
public boolean isMutable() {
return false;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public int hashCode() {
return (new Integer(this.getValue().toString())).intValue();
}
public String getResourceKey() {
if (resourceKey == null)
resourceKey = resolveFromValue(this.value).resourceKey;
return resourceKey;
}
public void setResourceKey(String resourceKey) {
this.resourceKey = resourceKey;
}
}
public abstract class EnumarationType extends EnumarationTypeBase {
protected static int[] SQL_TYPES = { Types.VARCHAR };
public EnumarationType() {
}
public EnumarationType(Integer value, String label) {
this.value = value.toString();
this.label = label;
}
public EnumarationType(String value, String label) {
this.value = value.toString();
this.label = label;
}
public EnumarationType(Integer value, String label, String resourceKey) {
this.value = value.toString();
this.label = label;
this.resourceKey = resourceKey;
}
public String getValue() {
return (String) value;
}
public BigDecimal getBigDecimalValue() {
BigDecimal tValue = new BigDecimal(getValue());
return tValue;
}
public void setValue(String value) {
this.value = value;
}
}
So how could i define a manytomany relationship between the entity Platform and non-entity usertype MimeType.
Please help.
I solved the problem. Here is the working code
...
#ElementCollection(targetClass = MimeType.class,fetch=FetchType.EAGER)
#CollectionTable(name = "PLATFORM_MIME_TYPE", joinColumns = #JoinColumn(name = "PLATFORM_ID"))
#Enumerated(EnumType.ORDINAL)
#Column(name = "MIME_TYPE_ID", columnDefinition="integer")
#Type(
type = Constants.ENUMERATION_TYPE,
parameters = {
#Parameter(
name = "enumClass",
value = "com.ba.reme.model.enums.MimeType"),
#Parameter(
name = "identifierMethod",
value = "toInt"),
#Parameter(
name = "valueOfMethod",
value = "fromInt")
}
)
private Set<MimeType> supportedMimeTypes;
...
And the MimeType enum :
public enum MimeType {
XML(1),
JSON(2),
RSS(3);
private int value;
MimeType(int value) {
this.value = value;
}
// the identifierMethod
public int toInt() {
return value;
}
// the valueOfMethod
public static MimeType fromInt(int value) {
switch(value) {
case 2: return JSON;
case 3: return RSS;
default: return XML;
}
}
public String toString() {
switch(this) {
case RSS: return "rss";
case JSON: return "json";
default: return "xml";
}
}
}
I am building a REST service on Spring 3.1. I am using #EnableWebMVC annotation for that. Since my service will only be accepting JSON requests, I would also like to dump the incoming request into a MongoDB collection for logging (and, later, for data transformation). I would like to access the raw JSON Request (which I could do on a non-spring implementation using "#Content HttpServletRequest request" as a method parameter).
I am a Spring newbie. So, kindly help me with directions to achieve this. Thanks!
UPDATE: The issue is not completely resolved. Only my tests with GET worked. It fails with POST. Therefore unchecked the accepted answer
The issue is, even if I create a HttpServletRequestWrapper, I cannot forward the request after I process and wrap the request. Here is what happens:
Interceptor:
public class DBLogInterceptor extends HandlerInterceptorAdapter {
MyRequestWrapper requestWrapper;
private final static Logger logger = Logger.getLogger(DBLogInterceptor.class);
#Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception
{
requestWrapper = new MyRequestWrapper(request);
// Code removed, but it just dumps requestWrapper.getBody() into DB
return super.preHandle(requestWrapper, response, handler);
}
}
HTTP POST Servicing method
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
#ResponseBody
public String updateEntity(#RequestBody Employee emp) {
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
Now I get an exception whenever I send a POST:
12:04:53,821 DEBUG DBLogInterceptor:22 - {"name":"Van Damme","dept":"Applied Martial Arts"}
12:04:53,843 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.test.webapp.login.domain.Employee] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter#154174f9]
12:04:53,850 DEBUG ExceptionHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Stream closed
12:04:53,854 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,854 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,859 DEBUG DispatcherServlet:910 - Could not complete request
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224)
at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785)
at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1914)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I expected the HttpServletRequestWrapper to be taking care of caching the request. But it doesn't happen somehow.
Using the HttpServletRequest object, you can get access to the URL the client used to make the request, the method used (GET, POST, PUT, etc), the query string, and headers.
Getting the RequestBody may be a bit trickier and may require using the HttpServletRequestWrapper object. Since the request body can only be read once, you'll need to extend the wrapper to access it so that your target controller can still access it later to deserialize your JSON into POJO objects.
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
To access the requests in a central location, you can use either a Filter or a Spring Interceptor. Both of these are invoked prior to the request being delegated to the controller, and both have access to the servlet.
Here is an actual Logging example using a Spring Interceptor:
package com.vaannila.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler. HandlerInterceptorAdapter;
public class LoggerInterceptor extends HandlerInterceptorAdapter {
static Logger logger = Logger.getLogger(LoggerInterceptor.class);
static {
BasicConfigurator.configure();
}
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
logger.info("Before handling the request");
return super.preHandle(request, response, handler);
}
#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("After handling the request");
super.postHandle(request, response, handler, modelAndView);
}
#Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info("After rendering the view");
super.afterCompletion(request, response, handler, ex);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<bean id="handlerMapping" class="org.springframework.web.servlet.handler. BeanNameUrlHandlerMapping" p:interceptors-ref="loggerInterceptor" />
<bean id="loggerInterceptor" class="com.vaannila.interceptor.LoggerInterceptor" />
<bean id="userService" class="com.vaannila.service.UserServiceImpl" />
<bean name="/userRegistration.htm" class="com.vaannila.web.UserController" p:userService-ref="userService" p:formView="userForm" p:successView="userSuccess" />
</beans>
In the LoggerInterceptor, you could use the following code to access the request:
MyRequestWrapper myRequestWrapper = new MyRequestWrapper((HttpServletRequest) request);
String body = myRequestWrapper.getBody();
String clientIP = myRequestWrapper.getRemoteHost();
int clientPort = request.getRemotePort();
String uri = myRequestWrapper.getRequestURI();
System.out.println(body);
System.out.println(clientIP);
System.out.println(clientPort);
System.out.println(uri);
I doubt if HttpServletRequestWrapper can ever work... Take a look at the DispatcherServlet implementation:
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;
}
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
It passes reference to "processedRequest" still, which refers to a HttpServletRequest request whose stream has already been read.
I know this is an old question, but for those of you that are still looking for a solution, this worked for me:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Map<String, String> requestMap = this
.getTypesafeRequestMap(httpServletRequest);
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
httpServletResponse);
final StringBuilder logMessage = new StringBuilder(
"REST Request - ").append("[HTTP METHOD:")
.append(httpServletRequest.getMethod())
.append("] [PATH INFO:")
.append(httpServletRequest.getPathInfo())
.append("] [REQUEST PARAMETERS:").append(requestMap)
.append("] [REQUEST BODY:")
.append(bufferedRequest.getRequestBody())
.append("] [REMOTE ADDRESS:")
.append(httpServletRequest.getRemoteAddr()).append("]");
chain.doFilter(bufferedRequest, bufferedResponse);
logMessage.append(" [RESPONSE:")
.append(bufferedResponse.getContent()).append("]");
logger.debug(logMessage.toString());
} catch (Throwable a) {
logger.error(a.getMessage());
}
}
private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
Map<String, String> typesafeRequestMap = new HashMap<String, String>();
Enumeration<?> requestParamNames = request.getParameterNames();
while (requestParamNames.hasMoreElements()) {
String requestParamName = (String) requestParamNames.nextElement();
String requestParamValue = request.getParameter(requestParamName);
typesafeRequestMap.put(requestParamName, requestParamValue);
}
return typesafeRequestMap;
}
#Override
public void destroy() {
}
private static final class BufferedRequestWrapper extends
HttpServletRequestWrapper {
private ByteArrayInputStream bais = null;
private ByteArrayOutputStream baos = null;
private BufferedServletInputStream bsis = null;
private byte[] buffer = null;
public BufferedRequestWrapper(HttpServletRequest req)
throws IOException {
super(req);
// Read InputStream and store its content in a buffer.
InputStream is = req.getInputStream();
this.baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int read;
while ((read = is.read(buf)) > 0) {
this.baos.write(buf, 0, read);
}
this.buffer = this.baos.toByteArray();
}
#Override
public ServletInputStream getInputStream() {
this.bais = new ByteArrayInputStream(this.buffer);
this.bsis = new BufferedServletInputStream(this.bais);
return this.bsis;
}
String getRequestBody() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
this.getInputStream()));
String line = null;
StringBuilder inputBuffer = new StringBuilder();
do {
line = reader.readLine();
if (null != line) {
inputBuffer.append(line.trim());
}
} while (line != null);
reader.close();
return inputBuffer.toString().trim();
}
}
private static final class BufferedServletInputStream extends
ServletInputStream {
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
#Override
public int available() {
return this.bais.available();
}
#Override
public int read() {
return this.bais.read();
}
#Override
public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
}
public class TeeServletOutputStream extends ServletOutputStream {
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two) {
targetStream = new TeeOutputStream(one, two);
}
#Override
public void write(int arg0) throws IOException {
this.targetStream.write(arg0);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
}
public class BufferedResponseWrapper implements HttpServletResponse {
HttpServletResponse original;
TeeServletOutputStream tee;
ByteArrayOutputStream bos;
public BufferedResponseWrapper(HttpServletResponse response) {
original = response;
}
public String getContent() {
return bos.toString();
}
public PrintWriter getWriter() throws IOException {
return original.getWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (tee == null) {
bos = new ByteArrayOutputStream();
tee = new TeeServletOutputStream(original.getOutputStream(),
bos);
}
return tee;
}
#Override
public String getCharacterEncoding() {
return original.getCharacterEncoding();
}
#Override
public String getContentType() {
return original.getContentType();
}
#Override
public void setCharacterEncoding(String charset) {
original.setCharacterEncoding(charset);
}
#Override
public void setContentLength(int len) {
original.setContentLength(len);
}
#Override
public void setContentType(String type) {
original.setContentType(type);
}
#Override
public void setBufferSize(int size) {
original.setBufferSize(size);
}
#Override
public int getBufferSize() {
return original.getBufferSize();
}
#Override
public void flushBuffer() throws IOException {
tee.flush();
}
#Override
public void resetBuffer() {
original.resetBuffer();
}
#Override
public boolean isCommitted() {
return original.isCommitted();
}
#Override
public void reset() {
original.reset();
}
#Override
public void setLocale(Locale loc) {
original.setLocale(loc);
}
#Override
public Locale getLocale() {
return original.getLocale();
}
#Override
public void addCookie(Cookie cookie) {
original.addCookie(cookie);
}
#Override
public boolean containsHeader(String name) {
return original.containsHeader(name);
}
#Override
public String encodeURL(String url) {
return original.encodeURL(url);
}
#Override
public String encodeRedirectURL(String url) {
return original.encodeRedirectURL(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeUrl(String url) {
return original.encodeUrl(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeRedirectUrl(String url) {
return original.encodeRedirectUrl(url);
}
#Override
public void sendError(int sc, String msg) throws IOException {
original.sendError(sc, msg);
}
#Override
public void sendError(int sc) throws IOException {
original.sendError(sc);
}
#Override
public void sendRedirect(String location) throws IOException {
original.sendRedirect(location);
}
#Override
public void setDateHeader(String name, long date) {
original.setDateHeader(name, date);
}
#Override
public void addDateHeader(String name, long date) {
original.addDateHeader(name, date);
}
#Override
public void setHeader(String name, String value) {
original.setHeader(name, value);
}
#Override
public void addHeader(String name, String value) {
original.addHeader(name, value);
}
#Override
public void setIntHeader(String name, int value) {
original.setIntHeader(name, value);
}
#Override
public void addIntHeader(String name, int value) {
original.addIntHeader(name, value);
}
#Override
public void setStatus(int sc) {
original.setStatus(sc);
}
#SuppressWarnings("deprecation")
#Override
public void setStatus(int sc, String sm) {
original.setStatus(sc, sm);
}
#Override
public String getHeader(String arg0) {
return original.getHeader(arg0);
}
#Override
public Collection<String> getHeaderNames() {
return original.getHeaderNames();
}
#Override
public Collection<String> getHeaders(String arg0) {
return original.getHeaders(arg0);
}
#Override
public int getStatus() {
return original.getStatus();
}
}
}
Then simply register the filter in web.xml and you're done. All credits to: http://wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431 (I just did some minor fix to it).
Hey can you try with this:
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "/employee")
#ResponseBody
public String updateEntity(#RequestBody Employee emp) {
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
Here: it you proving URI with the '/' it allows all the operations to perform. such as get post update and delete with same URI value.
Currently in spring-mvc repo, interceptors are invoked in DispatcherServlet#doDispatch(...):
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
...
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
try {
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
...
Can I define my own DispatcherServlet, and override doDispatch(...) to inject a HttpRequestWrapper with a ByteArrayInputStream on getInputStream()?
...
#Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
throws Exception {
RequestWrapper wrappedRequest = new RequestWrapper(request);
logger.debug("injecting RequestWrapper: " + wrappedRequest);
super.doDispatch(wrappedRequest, response);
}
...
Will this work for the above situation?
I make a Ouputstream version without any dependency to 3rd party libs for easier re-use. You can use this 2 wrapper class to get the request & response body easily.
But anyway, I have to use a filter to do this instead of interceptor. Because as #user1323865 mentioned, in spring 4, the processedRequest is used in both interceptor and handler, so you cannot use these methods for interceptor.
Also you can find some help in this link if you're using Writer version instead.
Capture and log the response body
public class BufferedRequestWrapper extends HttpServletRequestWrapper
{
private static final class BufferedServletInputStream extends ServletInputStream
{
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais)
{
this.bais = bais;
}
#Override
public int available()
{
return this.bais.available();
}
#Override
public int read()
{
return this.bais.read();
}
#Override
public int read(byte[] buf, int off, int len)
{
return this.bais.read(buf, off, len);
}
}
private byte[] mBodyBuffer;
public BufferedRequestWrapper(HttpServletRequest request) throws IOException
{
super(request);
InputStream in = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) > 0)
{
baos.write(buffer, 0, bytesRead);
}
mBodyBuffer = baos.toByteArray();
}
public String getRequestBody()
{
return new String(mBodyBuffer, Charset.forName("UTF-8"));
}
#Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
#Override
public ServletInputStream getInputStream()
{
ByteArrayInputStream in = new ByteArrayInputStream(mBodyBuffer);
return new BufferedServletInputStream(in);
}
}
public class BufferedResponseWrapper extends HttpServletResponseWrapper
{
private TeeServletOutputStream mTeeOutputStream;
private static class TeeOutputStream extends OutputStream
{
private OutputStream mChainStream;
private OutputStream mTeeStream;
public TeeOutputStream(OutputStream chainStream, OutputStream teeStream)
{
mChainStream = chainStream;
mTeeStream = teeStream;
}
#Override
public void write(int b) throws IOException
{
mChainStream.write(b);
mTeeStream.write(b);
mTeeStream.flush();
}
#Override
public void close() throws IOException
{
flush();
mChainStream.close();
mTeeStream.close();
}
#Override
public void flush() throws IOException
{
mChainStream.close();
}
}
public class TeeServletOutputStream extends ServletOutputStream
{
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two)
{
targetStream = new TeeOutputStream(one, two);
}
#Override
public void write(int b) throws IOException
{
this.targetStream.write(b);
}
#Override
public void flush() throws IOException
{
super.flush();
this.targetStream.flush();
}
#Override
public void close() throws IOException
{
super.close();
this.targetStream.close();
}
}
private ByteArrayOutputStream mByteArrayOutputStream;
public BufferedResponseWrapper(HttpServletResponse response) throws IOException
{
super(response);
mByteArrayOutputStream = new ByteArrayOutputStream();
mTeeOutputStream = new TeeServletOutputStream(super.getResponse().getOutputStream(), mByteArrayOutputStream);
}
#Override
public PrintWriter getWriter() throws IOException
{
return super.getResponse().getWriter();
}
#Override
public ServletOutputStream getOutputStream() throws IOException
{
return mTeeOutputStream;
}
public String getResponseBody()
{
return mByteArrayOutputStream.toString();
}
}
One simple way to do this would be to get the request body as String and then parse as a Java object. You can use this String then as you want.
So in your example:
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
#ResponseBody
public String updateEntity(#RequestBody String empAsString) {
// Do whatever with the json as String
System.out.println(empAsString);
// Transform it into the Java Object you want
ObjectMapper mapper = new ObjectMapper();
Employee emp = mapper.readValue(empAsString, Employee.class);
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
As a note, if you need it as a list you can use:
List<Employee> eventsList =
mapper.readValue(jsonInString, mapper.getTypeFactory().constructCollectionType(List.class, Employee.class));
You need to implement the requestWrapper as follows:
public class DocVerificationRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public DocVerificationRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
#Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setReadListener(ReadListener listener) {
// TODO Auto-generated method stub
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
and then inside the chain.doFilter method of filter class pass the requestWrapper object instead of the request object as follows:
#Override
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("checking token in filter");
HttpServletRequest request = (HttpServletRequest) arg0;
DocVerificationRequestWrapper myRequestWrapper = new DocVerificationRequestWrapper((HttpServletRequest) request);
String body = myRequestWrapper.getBody();
logger.info("body = "+body);
Token token = null;
try {
JSONObject jsonObj = new JSONObject(body);
JSONObject tokenObj = (JSONObject) jsonObj.get("token");
Gson gson = new Gson();
token = gson.fromJson(tokenObj.toString(), Token.class);
if(null != token) {
if(userVerificationService==null){
ServletContext servletContext = request.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
userVerificationService = webApplicationContext.getBean(UserVerificationService.class);
}
String verStatus = userVerificationService.verifyUser(token);
logger.info("verStatus = "+verStatus);
if(verStatus != null && verStatus.equalsIgnoreCase("success")) {
chain.doFilter(myRequestWrapper, response); //here replacing request with requestWrapper
}else
logger.error("Invalid token");
}else {
logger.error("token missing.");
}
} catch (JSONException e) {
logger.error("exception in authetication filter " + e);
}
}
Thus solving the IOStream closed exception.
For getting data from Body you can try to read and recreate InputStream in RequestBodyAdviceAdapter:
#ControllerAdvice
public class CustomRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {
#Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
String body = IOUtils.toString(inputMessage.getBody(), UTF_8.name());
HttpInputMessage myMessage = new HttpInputMessage(){
#Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(body.getBytes());
}
#Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
};
System.out.println("Data from Body: " + body);
return super.beforeBodyRead(myMessage, parameter, targetType, converterType);
}
#Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println("Data from Body is empty");
return super.handleEmptyBody(body, inputMessage, parameter, targetType, converterType);
}
#Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
}
#Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
}
You can simply use :
import org.apache.commons.io.IOUtils;
import java.nio.charset.Charset;
String requestBody = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8").toString());
In my experiences,just develop as follows:
Using the filter in order to wrapper ServletRequest,then you can repeatly use getting request input stream.